NGC 4258 (UGC 7353)

Галактика найдена из пересечения HYPERLEDA и https://arxiv.org/pdf/1608.06735v1.pdf.


In [1]:
from IPython.display import HTML
from IPython.display import Image
import os

%pylab
%matplotlib inline
%run ../../utils/load_notebook.py


Using matplotlib backend: Qt5Agg
Populating the interactive namespace from numpy and matplotlib

In [2]:
from photometry import *


importing Jupyter notebook from photometry.ipynb
Using matplotlib backend: Qt5Agg
Populating the interactive namespace from numpy and matplotlib

In [3]:
from instabilities import *


importing Jupyter notebook from instabilities.ipynb
Using matplotlib backend: Qt5Agg
Populating the interactive namespace from numpy and matplotlib

In [4]:
from utils import *


importing Jupyter notebook from utils.ipynb

In [5]:
name = 'N4258'
gtype = 'SABb' #LEDA, 'SBbc' from Heraudeau98
incl = 65.  #mean value
distance = 8.0*(73./75.) # corrected to Noordermeer H0
scale = 0.038 #kpc/arcsec according to Noordermeer H0

data_path = '../../data/n4258_u7353'
sin_i, cos_i = np.sin(incl*np.pi/180.), np.cos(incl*np.pi/180.)

In [6]:
%%javascript 
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')


Оглавление

Статьи

TODO: add arcticles

Разное


In [7]:
os.chdir(data_path)

# Данные из NED
HTML('<iframe src=http://ned.ipac.caltech.edu/cgi-bin/objsearch?objname=ngc+4258&extend=no&hconst=\
73&omegam=0.27&omegav=0.73&corr_z=1&out_csys=Equatorial&out_equinox=J2000.0&obj_sort=RA+or+Longitude&of=pre_text&zv_breaker=\
30000.0&list_limit=5&img_stamp=YES width=1000 height=350></iframe>')


Out[7]:

In [8]:
# Данные из HYPERLEDA
HTML('<iframe src=http://leda.univ-lyon1.fr/ledacat.cgi?o=ngc4258 width=1000 height=350></iframe>')


Out[8]:

In [9]:
#SDSS
Image('n4258_SDSS.jpg', width=300)


Out[9]:

Из выборки http://cosmo.nyu.edu/hogg/rc3/ с маштабом:


In [10]:
Image('n4258_SDSS_labeled.jpg', width=500)


Out[10]:

In [11]:
#JHK
Image('n4258_2MASS.jpg', width=300)


Out[11]:

In [12]:
Image('http://www.spitzer.caltech.edu/uploaded_files/graphics/high_definition_graphics/0008/2016/ssc2007-06a_Ti.jpg', width=300)


Out[12]:

In [13]:
Image('http://www.spitzer.caltech.edu/uploaded_files/graphics/high_definition_graphics/0010/1167/sig14-020a_Inline.jpg', width=300)


Out[13]:

In [14]:
Image('http://www.spitzer.caltech.edu/uploaded_files/graphics/high_definition_graphics/0010/1185/sig14-020_Inline.jpg', width=300)


Out[14]:

А также просто куча (~1500) изображений с HST, я правда хорошего там не нашел.

Вот в этой статье https://arxiv.org/pdf/1612.05655.pdf есть ссылка на величину R25 (примерно 9 минут или 20 кпк), а также картинка (возможно в $K$) со скоплениями:


In [15]:
Image('GCC_and_R25.png')


Out[15]:

Кинематические данные по звездам

Дисперсии скоростей и кривая вращения - есть в Heraudeau 1998 http://adsabs.harvard.edu/cgi-bin/bib_query?1998A%26AS..133..317H до ~ 50'' (1 разрез), PA=$150^{\circ}$

TODO: понять, исправлено ли за наклон

Кривая вращения


In [16]:
# Данные по звездной кинематике Heraudeau+1998 вдоль большой полуоси (не исправленные за наклон?) - из HYPERLEDA
r_ma, vel_ma, e_vel_ma, sig_ma, e_sig_ma = zip(*np.loadtxt("her98_kinem.dat", float))

fig = plt.figure(figsize=[8,5])
plt.errorbar(r_ma, vel_ma, e_vel_ma, fmt='.', marker='.', mew=0, label="Heraudeau 1998 stars maj")
plt.legend()
plt.ylim(-350., 350.);



In [17]:
Image('her98_rot.png') #оригинал


Out[17]:

Приближение:


In [18]:
r_ma_b, vel_ma_b, e_vel_b = zip(*sorted(zip(np.abs(r_ma), np.abs(vel_ma), e_vel_ma)))

In [19]:
# %%time
fig = plt.figure(figsize=[8,4])
plt.errorbar(r_ma_b, vel_ma_b, yerr=e_vel_b, fmt='.', marker='.', mew=0, color='blue', label = 'Her98 star maj')

test_points = np.linspace(0.0, max(r_ma_b), 100)

poly_star = poly1d(polyfit(r_ma_b, vel_ma_b, deg=7))
plt.plot(test_points, poly_star(test_points), '-', label='poly deg=7')

def w(arr):
    return map(lambda l: 1/(1. + l**2), arr)

import scipy.interpolate as inter

spl = inter.UnivariateSpline(r_ma_b, vel_ma_b, k=3, s=10000., w=w(e_vel_b))
plt.plot(test_points, spl(test_points), '-', label='spl s=10000 w^2')

spl = inter.UnivariateSpline(r_ma_b, vel_ma_b, k=3, s=1800.)
plt.plot(test_points, spl(test_points), '-', label='spl s=1800')

plt.legend(loc='lower right')
plt.ylim(0, 170);


C весами плохо получается, полином и обычный почти совпадают - берем их:


In [20]:
star_approx = spl

Дисперсии


In [21]:
r_sig_ma = r_ma #Heraudeau+1998

fig = plt.figure(figsize=[6., 4.])
plt.errorbar(r_sig_ma, sig_ma, yerr=e_sig_ma, fmt='.', marker='.', mew=0, color='blue', label=r'$maj\, Heraudeau $')

plt.xlabel('$R$')
plt.ylabel('$\sigma$')
plt.ylim(0, 350)
plt.legend();



In [22]:
Image('her98_sig.png') #из статьи


Out[22]:

In [23]:
r_sig_ma = map(abs, r_sig_ma)

fig = plt.figure(figsize=[6., 4.])
plt.errorbar(r_sig_ma, sig_ma, yerr=e_sig_ma, fmt='.', marker='.', mew=0, color='blue', label=r'$maj\, Heraudeau $')
plt.xlabel('$R$')
plt.ylabel('$\sigma$')
plt.ylim(0, 200)
plt.legend();


Для большой оси: $\sigma^2_{maj} = \sigma^2_{\varphi}\sin^2 i + \sigma^2_{z}\cos^2 i$, следовательно примерные ограничения $$\sigma_{maj} < \frac{\sigma_{maj}}{\sqrt{\sin^2 i + 0.49\cos^2 i}}< \sigma_R = \frac{\sigma_{maj}}{\sqrt{f\sin^2 i + \alpha^2\cos^2 i}} ~< \frac{\sigma_{maj}}{\sqrt{0.5\sin^2 i + 0.09\cos^2 i}} < \frac{\sqrt{2}\sigma_{maj}}{\sin i} (или \frac{\sigma_{maj}}{\sqrt{f}\sin i}),$$ или можно более точную оценку дать, если построить $f$ (сейчас $0.5 < f < 1$).

Для малой оси: $\sigma^2_{min} = \sigma^2_{R}\sin^2 i + \sigma^2_{z}\cos^2 i$ и ограничения $$\sigma_{min} < \frac{\sigma_{min}}{\sqrt{\sin^2 i + 0.49\cos^2 i}} < \sigma_R = \frac{\sigma_{min}}{\sqrt{\sin^2 i + \alpha^2\cos^2 i}} ~< \frac{\sigma_{min}}{\sqrt{\sin^2 i + 0.09\cos^2 i}} < \frac{\sigma_{min}}{\sin i}$$

Соответственно имеем 5 оценок из maj и 4 оценки из min.

У нас только большая - приближаем по ней.


In [24]:
spl_maj = inter.UnivariateSpline(r_sig_ma, sig_ma, k=3, s=10000.)
sig_maj_lim = max(r_sig_ma)

points = np.linspace(0.1, max(r_ma)+15., 100)

In [25]:
# TODO: find way to move to external file
@flat_end(sig_maj_lim)
def sig_R_maj_minmin(r, spl_maj=spl_maj):
    return spl_maj(r).item()

@flat_end(sig_maj_lim)
def sig_R_maj_min(r, spl_maj=spl_maj):
    return spl_maj(r).item()/sqrt(sin_i**2 + 0.49*cos_i**2)
    
@flat_end(sig_maj_lim)
def sig_R_maj_max(r, spl_maj=spl_maj):
    return spl_maj(r).item()/sqrt(0.5*sin_i**2 + 0.09*cos_i**2)

@flat_end(sig_maj_lim)
def sig_R_maj_maxmax(r, spl_maj=spl_maj):
    return spl_maj(r)*sqrt(2)/sin_i
    
@flat_end(sig_maj_lim)
def sig_R_maj_maxmaxtrue(r, spl_maj=spl_maj):
    return spl_maj(r)/sin_i/sqrt(sigPhi_to_sigR_real(r))

Используем соотношение $\sigma_{\varphi}^{2}/\sigma_{R}^{2}$, которое описывается уравнением ${\displaystyle \sigma_{\varphi}^{2}/\sigma_{R}^{2}=0.5\left(1+\frac{R}{\bar{v}_{\varphi}}\frac{d\bar{v}_{\varphi}}{dR}\right)}$ (Binney & Tremaine, 1987)


In [26]:
def sigPhi_to_sigR_real(R):
        return 0.5 * (1 + R*star_approx.derivative()(R) / star_approx(R))

plt.plot(test_points, [sigPhi_to_sigR_real(R) for R in test_points], 'd-', color='green')
plt.axhline(y=0.5)
plt.axhline(y=0.0)
plt.xlabel('$R$')
plt.ylabel(r"$\sigma_{\varphi}^2/\sigma_{R}^2$")
plt.ylim(0);



In [27]:
plt.errorbar(r_sig_ma, sig_ma, yerr=e_sig_ma, fmt='.', marker='.', mew=0, color='red', label='$\sigma_{los}^{maj}$')
plt.plot(points, map(sig_R_maj_minmin, points), label = 'minmin')
plt.plot(points, map(sig_R_maj_min, points), label = 'min')
plt.plot(points, map(sig_R_maj_max, points), label = 'max')
plt.plot(points, map(sig_R_maj_maxmax, points), label = 'maxmax')
plt.plot(points, map(sig_R_maj_maxmaxtrue, points), label = 'maxmaxtrue')

plt.legend()
plt.ylim(0,250)
plt.xlim(0,100);


Видно, что оценки почти не отличаются, только "настоящая" близка и к одной и к другой.

Данные по газу

Кривая вращения


In [28]:
Image('CO_rot.png') #from Sawada-Satoh 2007, правда [P.A.] = 86  -- НЕТ, ЭТО НЕ ТАК, ТОЛЬКО МОЛЕК. ДИСКА КАСАЕТСЯ. Сама картинка вроде для главной оси


Out[28]:

In [29]:
# Данные по кинематике газа Sawada-Satoh 2007 в CO
r_co, vel_co = zip(*np.loadtxt("CO_rot.dat", float, delimiter=','))
plt.plot(r_co, vel_co, 'o', label='CO Sawada-Satoh 2007')
plt.ylim(0, 250)
plt.xlim(0, 2250.)


Out[29]:
(0, 2250.0)

In [30]:
Image('HI_rot.png') #HI WHISP from van Eymeren 2011, PA=331(-180=151, все ок), R25=19.46kpc, разные цвета - это две стороны, черная - усредненная


Out[30]:

In [31]:
R25 = 19.46

# Данные по кинематике газа van Eymeren 2011 в HI
r_hi, vel_hi = zip(*np.loadtxt("HI_rot.dat", float, delimiter=','))
plt.plot(r_hi, vel_hi, 'd', label='HI Eymeren+2011')
plt.ylim(0, 250)
plt.xlim(-0.5, 2.)


Out[31]:
(-0.5, 2.0)

In [32]:
Image('CO_HI_rot.png') # CO+HI Sofue 97


Out[32]:

Тут точки не самое ценное, видно как ось проходит зато.


In [33]:
plt.plot([l/1000./calc_scale(7.2) for l in r_co], vel_co, '.', label='CO Sawada-Satoh 2007')
plt.plot([l*R25/calc_scale(7.8) for l in r_hi], vel_hi, 'd', label='HI Eymeren+2011')
plt.legend()


Out[33]:
<matplotlib.legend.Legend at 0xd1e5860>

Непонятно, что брать. Видимо с учетом того, что у $CO$ странный позиц. угол - берем $HI$:


In [34]:
r_hi = [l*R25/calc_scale(7.8) for l in r_hi]
r_co = [l/1000./calc_scale(7.2) for l in r_co]

In [35]:
fig = plt.figure(figsize=[10,6])
_1,_2, = [0.0,],[0.0,]
_1.extend(r_hi)
_2.extend(vel_hi)
_1,_2 = zip(*sorted(zip(_1,_2)))

gas_approx = poly1d(polyfit(_1, _2, deg=9))
test_points = np.linspace(0, max(r_hi), 100)
plt.plot(test_points, gas_approx(test_points), '--', label='poly approx')

spl_gas = inter.UnivariateSpline(_1, _2, k=3, s=2000.)
plt.plot(test_points, spl_gas(test_points), '-', label='spline')

plt.plot(r_hi, vel_hi, 'd', label='HI Eymeren+2011')

plt.ylim(0, 300)
plt.legend(loc='lower right');


А вот такой результат для $CO$ + HI:


In [36]:
_1,_2 = zip(*filter(lambda l: l[0] > 110., zip(r_hi, vel_hi)))
_1 = [0.] + list(r_co) + list(_1)
_2 = [0.] + list(vel_co) + list(_2)

fig = plt.figure(figsize=[10,6])

plt.plot(r_co, vel_co, '.', label='CO Sawada-Satoh+2007', color='b')
plt.plot(r_hi, vel_hi, 'd', label='HI Eymeren+2011')
# plt.plot(_1, _2, '.', label='CO+HI')

gas_approx = poly1d(polyfit(_1, _2, deg=9))
test_points = np.linspace(0, max(r_hi), 100)
plt.plot(test_points, gas_approx(test_points), '--', label='poly approx')

spl_gas = inter.UnivariateSpline(_1, _2, k=3, s=3900.)
plt.plot(test_points, spl_gas(test_points), '-', label='spline')


plt.ylim(0, 300)
plt.legend(loc='lower right');


Так наверное гораздо более обоснованно (хотя про угол конечно же есть сомнения).

Эпициклическая частота

Для случая бесконечного тонкого диска: $$\kappa=\frac{3}{R}\frac{d\Phi}{dR}+\frac{d^2\Phi}{dR^2}$$ где $\Phi$ - гравпотенциал, однако его знать не надо, т.к. есть проще формула: $$\kappa=\sqrt{2}\frac{\vartheta_c}{R}\sqrt{1+\frac{R}{\vartheta_c}\frac{d\vartheta_c}{dR}}$$


In [37]:
fig = plt.figure(figsize=[8, 4])
plt.plot(test_points, [epicyclicFreq_real(gas_approx, x, scale) for x in test_points], '-', label='poly')
plt.plot(test_points, [epicyclicFreq_real(spl_gas, x, scale) for x in test_points], '-', label='spline')
plt.xlabel('$R, arcsec$')
plt.ylabel('$\kappa,\, km/s/kpc$', fontsize=15)
plt.ylim(0, 1000)
plt.legend();


Достаточно сложно, учитывая что нас интересуют первые 50 секунд.

Поверхностная плотность газа

Данные $\Sigma_{HI}$ и $\Sigma_{H_2}$ https://arxiv.org/pdf/1608.06735v1.pdf

(необходимо иметь в виду, что общий профиль исправлен за гелий следующим образом $\Sigma_g = 1.36\times(\Sigma_{H_2} + \Sigma_{HI})$ и переход CO-to-H2 тоже конкретный)


In [38]:
# у них расстояние в работе 8.0, т.е. совсем немного отличается
gas_scale = calc_scale(8.)
print gas_scale


0.0387851358025

In [39]:
r_g_dens1, gas_dens1 = zip(*np.loadtxt("gas_dens_err.txt", float, delimiter=';'))
hi_yerr = np.abs((np.column_stack([gas_dens1[25::3], gas_dens1[26::3]])-np.column_stack([gas_dens1[24::3], gas_dens1[24::3]]))).T
h2_yerr = np.abs((np.column_stack([gas_dens1[1:24:3], gas_dens1[2:24:3]])-np.column_stack([gas_dens1[0:24:3], gas_dens1[0:24:3]]))).T

In [40]:
fig = plt.figure(figsize=[10, 7.5])

plt.errorbar([l/gas_scale for l in r_g_dens1[24::3]], gas_dens1[24::3], hi_yerr, fmt='bo', capsize=5)
plt.errorbar([l/gas_scale for l in r_g_dens1[0:24:3]], gas_dens1[0:24:3], h2_yerr, fmt='ro', capsize=5)
ax = plt.gca()
ax.set_yscale("log", nonposy='clip')
plt.ylim(0.01, 1000)
plt.xlim(0);



In [41]:
Image('u7353_gas_dens.png')


Out[41]:

Хорошо совпадает. Дальше будем работать с теми же что и раньше, а эти прибережем для финальной картинки. Единственное что все (и ошибки) надо исправить за расстояние и $X_{CO}$


In [42]:
gas_dens1 = [l*(8/distance)**2 for l in gas_dens1]
hi_yerr = hi_yerr*(8/distance)**2
h2_yerr = h2_yerr*(8/distance)**2

r_g_dens1 = [l/gas_scale for l in r_g_dens1]

In [43]:
r_g_dens, gas_dens = zip(*np.loadtxt("gas_data.dat", float, delimiter=','))

plt.semilogy([l/gas_scale for l in r_g_dens], gas_dens, 's');



In [44]:
plt.semilogy([l/gas_scale for l in r_g_dens[48:56]], gas_dens[48:56], 'o', color='r')
plt.semilogy([l/gas_scale for l in r_g_dens[56:]], gas_dens[56:], 'o');



In [45]:
plt.plot([l/gas_scale for l in r_g_dens[48:56]], gas_dens[48:56], '-o', color='r')
plt.plot([l/gas_scale for l in r_g_dens[56:]], gas_dens[56:], '-o') #только сумма
plt.xlim(0, 200);



In [46]:
r_HI_dens, HI_dens = [l/gas_scale for l in r_g_dens[:48]], gas_dens[:48]
r_mol_dens, mol_dens = [l/gas_scale for l in r_g_dens[48:56]], gas_dens[48:56]
r_g_dens, gas_dens = [l/gas_scale for l in r_g_dens[56:]], gas_dens[56:] #используем только полный газ

Посмотрим как сильно отличаются снятые точки:


In [47]:
import scipy.interpolate

y_interp = scipy.interpolate.interp1d(list(r_mol_dens), list(mol_dens))

def y_interp_(r):
    if r <= min(r_mol_dens):
        return y_interp(min(r_mol_dens))
    elif r < max(r_mol_dens):
        return y_interp(r)
    else:
        return 0.

In [48]:
plt.plot(r_g_dens, gas_dens, '-s', color='r')
plt.plot(r_HI_dens, [He_coeff*(y_interp_(l[0]) + l[1]) for l in zip(r_HI_dens, HI_dens)], '-o')
plt.xlim(0, 200);


Видно, что смещение есть по обеим осям, что понятно, т.к. снять сложно очень точно.

Надо исправить за другое расстояние (8.0) и $X_{CO}=1.9$. Сейчас исправим только за расстояние, т.к. фактор у нас пока такой же:


In [49]:
HI_dens = [l*(8/distance)**2 for l in HI_dens]
mol_dens = [l*(8/distance)**2 * (X_CO/1.9) for l in mol_dens]
gas_dens = [l*(8/distance)**2 for l in gas_dens]

In [50]:
plt.plot(r_HI_dens, HI_dens)
plt.plot(r_mol_dens, mol_dens)
plt.plot(r_g_dens, gas_dens);


И проинтегрировать массы:


In [51]:
import scipy.integrate as integrate
import scipy.interpolate

tmp_ = scipy.interpolate.interp1d(r_HI_dens, HI_dens)

result = integrate.quad(lambda l: 2*np.pi*l*tmp_(l), r_HI_dens[0], r_HI_dens[-1])
print (scale * 1000.)**2 * result[0]/1e9


7.87624425616
C:\Anaconda\lib\site-packages\scipy\integrate\quadpack.py:364: IntegrationWarning: The maximum number of subdivisions (50) has been achieved.
  If increasing the limit yields no improvement it is advised to analyze 
  the integrand in order to determine the difficulties.  If the position of a 
  local difficulty can be determined (singularity, discontinuity) one will 
  probably gain from splitting up the interval and calling the integrator 
  on the subranges.  Perhaps a special-purpose integrator should be used.
  warnings.warn(msg, IntegrationWarning)

In [52]:
tmp_ = scipy.interpolate.interp1d(r_mol_dens, mol_dens)

result = integrate.quad(lambda l: 2*np.pi*l*tmp_(l), r_mol_dens[0], r_mol_dens[-1])
print (scale * 1000.)**2 * result[0]/1e9


1.03008552589

Данные по фотометрии


In [53]:
Image('VRI_photom_profiles.png', width=400)


Out[53]:

In [54]:
r_phot, mu_phot = zip(*np.loadtxt("VRI_photom_profiles.dat", float, delimiter=','))

fig = plt.figure(figsize=[8, 5])
plt.plot(map(lambda l: l/scale, r_phot), mu_phot, 's') 
plt.ylim(22, 14)
plt.xlim(0, 100.);



In [55]:
r_phot = map(lambda l: l/scale, r_phot) # но не факт, что там такое расстояние - т.к. 
# All distances and linear sizes have been calculated from the radial
# velocities listed in Table 2, assuming H0 =ˆ 55 km s21 Mpc21 and q0=0 , 
# скорость у нее 488 км/с (я прикинул - вроде похоже, у нас расст. 8.97 МПк и из Хаббла похоже)

In [56]:
r_photI, mu_photI = r_phot[:43], mu_phot[:43]
r_photR, mu_photR = r_phot[43:86], mu_phot[43:86]
r_photV, mu_photV = r_phot[86:], mu_phot[86:]

fig = plt.figure(figsize=[8, 5])
plt.plot(r_photI, mu_photI, 's')
plt.plot(r_photR, mu_photR, 's')
plt.plot(r_photV, mu_photV, 's')
plt.ylim(22, 14)
plt.xlim(0, 100.);



In [57]:
from scipy.optimize import curve_fit

p_ = np.arange(0.1, 100., 0.1)

def func(x, a, b):
    return a * x + b

popt, pcov = curve_fit(func, r_photV[25:], mu_photV[25:])

fig = plt.figure(figsize=[16, 5])
plt.subplot(121)
plt.plot(r_photV, mu_photV, 's', label='V')
plt.plot(r_photV, map(lambda l: func(l, *popt), r_photV), '-', label="Fitted Curve")
plt.ylim(22, 14)
plt.xlim(0, 100.)
plt.legend()

plt.subplot(122)
M_to_L_V = 1.74
plt.plot(p_, [surf_density(mu=m, M_to_L=M_to_L_V, band='V') for m in [mu_disc(l, mu0=popt[1], h=1./popt[0]) for l in p_]], '-', label='V [M/L={:2.2f}]'.format(M_to_L_V))
plt.title('mu0={:2.1f}mag, h_d={:2.0f}"'.format(popt[1], 1./popt[0]))
plt.legend();



In [58]:
popt, pcov = curve_fit(func, r_photI[25:], mu_photI[25:])

fig = plt.figure(figsize=[16, 5])
plt.subplot(121)
plt.plot(r_photI, mu_photI, 's', label='I')
plt.plot(r_photI, map(lambda l: func(l, *popt), r_photI), '-', label="Fitted Curve")
plt.ylim(22, 14)
plt.xlim(0, 100.)
plt.legend()

plt.subplot(122)
M_to_L_I = 0.97
plt.plot(p_, [surf_density(mu=m, M_to_L=M_to_L_I, band='I') for m in [mu_disc(l, mu0=popt[1], h=1./popt[0]) for l in p_]], '-', label='I [M/L={:2.2f}]'.format(M_to_L_I))
plt.title('mu0={:2.1f}mag, h_d={:2.0f}"'.format(popt[1], 1./popt[0]))
plt.legend();


Много получается и параметры не похожи на след. работу.


In [59]:
all_photometry = []

Из последней статьи, данные в $I$:


In [60]:
# for I band
r_eff_I = 14.89
mu_eff_I = 18.48
n_I = 1.5
mu0d_I = 18.26
h_disc_I = 74.24

Сравнение с предыдущим:


In [61]:
p_ = np.arange(0.1, 300., 0.1)

r_phot, mu_phot = zip(*np.loadtxt("photom_I.dat", float, delimiter=','))

fig = plt.figure(figsize=[8, 5])
plt.plot(map(abs,r_phot), mu_phot, 's', label='this research')
plt.plot(r_photI, mu_photI, 's', label='prev. research H=55')
plt.plot(map(lambda l:l*9./(488./75.), r_photI), mu_photI, 's', label='prev. research H=75')
plt.ylim(23, 14)
plt.xlim(0, 100.)
plt.legend();


Либо выше недооценено и поэтому такие маленькие значения диска, либо все же пересчет в секунды другой (с нормальной константой Хаббла).


In [62]:
bulge_I = [mu_bulge(l, mu_eff=mu_eff_I, r_eff=r_eff_I, n=n_I) for l in p_]
disc_I = [mu_disc(l, mu0=mu0d_I, h=h_disc_I) for l in p_]
total_profile = total_mu_profile(bulge_I, disc_I)

fig = plt.figure(figsize=[8, 5])
plt.plot(r_phot, mu_phot, 's')
plt.plot(p_, bulge_I, '-', label='bulge', color='red')
plt.plot(p_, disc_I, '-', label='disk', color='green')
plt.plot(p_, total_profile, '-', label='sum', color='m')
plt.ylim(23, 14)
plt.legend();


Похоже. Оценка ${M/L}_I$ для диска у них в работе 0.97, посмотрим:


In [63]:
M_to_L_I = 0.97
surf_I = [surf_density(mu=m, M_to_L=M_to_L_I, band='I') for m in disc_I]

plt.plot(p_, surf_I, '-', label='YOSHINO I [M/L={:2.2f}]'.format(M_to_L_I))
plt.legend()


Out[63]:
<matplotlib.legend.Legend at 0x10ae3be0>

У них нет картинок для $V$ и $J$, но можно посмотреть на них тоже:


In [64]:
# for V band
r_eff_V = 10.34
mu_eff_V = 18.57
n_V = 1.5
mu0d_V = 19.54
h_disc_V = 78.55
M_to_L_V = 1.74
disc_V = [mu_disc(l, mu0=mu0d_V, h=h_disc_V) for l in p_]

In [65]:
# for J band
r_eff_J = 7.31
mu_eff_J = 16.43
n_J = 1.5
mu0d_J = 16.37
h_disc_J = 38.95
M_to_L_J = 0.95
disc_J = [mu_disc(l, mu0=mu0d_J, h=h_disc_J) for l in p_]

In [66]:
surf_V = [surf_density(mu=m, M_to_L=M_to_L_V, band='V') for m in disc_V]
surf_J = [surf_density(mu=m, M_to_L=M_to_L_J, band='J') for m in disc_J]

plt.plot(p_, surf_I, '-', label='YOSHINO I [M/L={:2.2f}]'.format(M_to_L_I))
plt.plot(p_, surf_V, '-', label='YOSHINO V [M/L={:2.2f}]'.format(M_to_L_V))
plt.plot(p_, surf_J, '-', label='YOSHINO J [M/L={:2.2f}]'.format(M_to_L_J))
plt.ylabel('$M_{sun}/{pc}^2$', fontsize=15.)
plt.legend()


Out[66]:
<matplotlib.legend.Legend at 0x10acda90>

В $J$ похоже что-то не то, возьмем другие две.

Действительно ли это много? Да, похоже таких массивных дисков не бывает.


In [67]:
all_photometry.append(('YOSHINO I', r_eff_I, mu_eff_I, n_I, mu0d_I, h_disc_I, M_to_L_I, 
                       lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=M_to_L_I, band='I')))

all_photometry.append(('YOSHINO V', r_eff_V, mu_eff_V, n_V, mu0d_V, h_disc_V, M_to_L_V, 
                       lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_V, h=h_disc_V), M_to_L=M_to_L_V, band='V')))

all_photometry.append(('YOSHINO J', r_eff_J, mu_eff_J, n_J, mu0d_J, h_disc_J, M_to_L_J, 
                       lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_J, h=h_disc_J), M_to_L=M_to_L_J, band='J')))

In [68]:
# for 3.6 band
dist_36 =  8.17 #Mpc
r_eff_36 = np.power(10., 2.77)/scale/1000./(dist_36/8.97) #pc
mu_eff_36 = 17.41
n_36 = 2.8
mu0d_36 = 18.82
h_disc_36 = np.power(10., 3.5)/scale/1000./(dist_36/8.97) #because original is Log(), pc

Тут нужно учитывать, что эти параметры cкорее всего в AB-mag и нуждаются в доп. исправлении.


In [69]:
M_to_L_s4g = s4g_mass_to_light(-21.328, -20.881)
M_to_L_s4g


Out[69]:
0.65393261738835051

In [70]:
surf_36 = [s4g_surf_density(m, M_to_L=M_to_L_s4g) for m in [mu_disc(l, mu0=mu0d_36, h=h_disc_36) for l in p_]]

plt.plot(p_, surf_36, '-', label='3.6 [M/L={:2.2f}]'.format(0.6))
plt.legend()


Out[70]:
<matplotlib.legend.Legend at 0xf1cbbe0>

Оч.большие. Можем сравнить еще с калибровками McGaugh:


In [71]:
bv_color = 0.77
mcgaugh_mass_to_light(bv_color, 'mu36')


Out[71]:
array([ 0.47,  0.58,  0.7 ,  0.62])

Ну да, тут все похоже честно. Правда очень похоже, что нужно приводить диск в положение плашмя, так что добавим исправленную модель тоже:


In [72]:
all_photometry.append(('SPITZER 3.6', r_eff_36, mu_eff_36, n_36, mu0d_36, h_disc_36, M_to_L_s4g, 
                       lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=M_to_L_s4g)))

print mu_face_on(mu0d_36, cos_i)

all_photometry.append(('SPITZER 3.6 faceon', r_eff_36, mu_eff_36, n_36, mu_face_on(mu0d_36, cos_i), h_disc_36, M_to_L_s4g, 
                       lambda l: s4g_surf_density(mu_disc(l, mu0=mu_face_on(mu0d_36, cos_i), h=h_disc_36), M_to_L=M_to_L_s4g)))


19.7551293515

И наконец GALFIT в $K$ из http://iopscience.iop.org/article/10.1088/0004-637X/780/1/69/pdf

Тип тут SAB(s)bc, есть еще дополнительные компоненты - idisk, bar, spir


In [73]:
Image('https://s3.amazonaws.com/aasie/images/0004-637X/780/1/69/apj488463f25_hr.jpg', width=400)


Out[73]:

In [74]:
# используем вторую модель, т.к. она лучше; 
# также надо пересчитывать из светимости яркость - возьму поверхн яркость с картинки - примерно 17.8
m_b_K = 9.24 
r_eff_K = 6.27
n_K = 3.26 
m_d_K = 6.00
h_disc_K = 146.

In [75]:
M_to_L_K = bell_mass_to_light(bv_color, 'K', 'B-V') #оценку берем из пред. работы
M_to_L_K


Out[75]:
0.79058760299863684

In [76]:
surf_K = [surf_density(mu=m, M_to_L=M_to_L_K, band='K') for m in [mu_disc(l, mu0=17.8, h=h_disc_K) for l in p_]]

plt.plot(p_, surf_K, '-', label='K [M/L={:2.2f}]'.format(M_to_L_K))
plt.legend()


Out[76]:
<matplotlib.legend.Legend at 0xccbf278>

Вполне нормальная оценка.


In [77]:
all_photometry.append(('GALFIT K', r_eff_K, None, n_K, 17.8, h_disc_K, M_to_L_K, 
                       lambda l: surf_density(mu=mu_disc(l, mu0=17.8, h=h_disc_K), M_to_L=M_to_L_K, band='K')))

S4G фоометрия с сайта (надо пересчитать масштаб из пикселей и поверхностую яркость из абс. зв. величины):


In [78]:
h_disc_s4g = 238.3528*0.75
mu0d_s4g =  3.24 - (log10((9.9858 + 5*log10(h_disc_s4g*scale) + 38.57)/4.255) - 8)/0.4
h_disc_s4g, mu0d_s4g


Out[78]:
(178.7646, 20.507390201117794)

Масштаб диска конечно какой-то совсем уж не реалистичный.


In [79]:
p_ = np.arange(0.1, 200., 0.1)

surf_s4g = [s4g_surf_density(mu_disc(l, mu0=mu0d_s4g, h=h_disc_s4g), M_to_L_s4g) for l in p_]
plt.plot(p_, surf_s4g, '-', label='S4G [M/L={:2.2f}]'.format(M_to_L_s4g))
plt.legend();



In [80]:
all_photometry.append(('S4G 3.6', None, None, None, mu0d_s4g, h_disc_s4g, M_to_L_s4g, 
                       lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_s4g, h=h_disc_s4g), M_to_L_s4g)))

Общая картинка:


In [81]:
for photom in all_photometry:
    plt.plot(p_, map(photom[-1], p_), '-', label=photom[0].format(M_to_L_I))
plt.ylabel('$M_{sun}/{pc}^2$', fontsize=15.)
plt.legend(loc='best')
plt.legend()


Out[81]:
<matplotlib.legend.Legend at 0xec9c160>

In [82]:
show_all_photometry_table(all_photometry, scale)


+------+--------------------+---------+----------+--------+---------+----------+-------+-------------+-----------+
|      | Name               |   r_eff |   mu_eff |      n |   mu0_d |   h_disc |   M/L | M_d/M_sun   |   Sigma_0 |
|------+--------------------+---------+----------+--------+---------+----------+-------+-------------+-----------|
| 0.00 | YOSHINO I          |   14.89 |    18.48 |   1.50 |   18.26 |    74.24 |  0.97 | 4.39E+10.   |       878 |
| 1.00 | YOSHINO V          |   10.34 |    18.57 |   1.50 |   19.54 |    78.55 |  1.74 | 5.41E+10.   |       967 |
| 2.00 | YOSHINO J          |    7.31 |    16.43 |   1.50 |   16.37 |    38.95 |  0.95 | 4.50E+10.   |      3271 |
| 3.00 | SPITZER 3.6        |   17.01 |    17.41 |   2.80 |   18.82 |    91.37 |  0.65 | 8.45E+10.   |      1116 |
| 4.00 | SPITZER 3.6 faceon |   17.01 |    17.41 |   2.80 |   19.76 |    91.37 |  0.65 | 3.57E+10.   |       471 |
| 5.00 | GALFIT K           |    6.27 |   nan    |   3.26 |   17.80 |   146.00 |  0.79 | 1.01E+11.   |       523 |
| 6.00 | S4G 3.6            |  nan    |   nan    | nan    |   20.51 |   178.76 |  0.65 | 6.84E+10.   |       236 |
+------+--------------------+---------+----------+--------+---------+----------+-------+-------------+-----------+

Сравнение с Кривой вращения тонкого диска

Можно провести тест-сравнение с кривой вращения тонкого диска при заданной фотометрии, если она слишком массивная - то не брать ее (это ограничение сверху).


In [83]:
fig = plt.figure(figsize=[10,6])

plt.plot(test_points, spl_gas(test_points), '-', label='spline')

plt.plot(_1, _2, '.', label='CO+HI')

for photom in all_photometry:
    plt.plot(test_points, map(lambda l: disc_vel(l, photom[7](0), photom[5], scale), test_points), '--', label=photom[0])


plt.ylim(0, 300)
plt.xlim(0, 300)
plt.legend(loc='best');


Видно, что $J$ не подходит, да и для $K$ слишком большой диск получился, да и 3.6 массивно слишком. Неплохо смотрятся $I$ и $V$.

Кривая вращения в $I$ похожа на картинку из статьи (макс на 150 примерно).

Зоны звездообразования

$\rm{H_{\alpha}}$, $UV$


In [84]:
Image('halpha.png', width=1700) #две картинки - Halpha и UV


Out[84]:

In [85]:
Image('halpha_dist.png', width=600)


Out[85]:

In [86]:
Image('large-fg16_19.jpeg')


Out[86]:

Multiwavelength imaging of XUV-disk galaxies. For each object we present (a) GALEX FUVand NUV, (b) 2MASS-Ks, (c) DSS2-red, and (d ) SDSS-DR5 imaging (when available). In the case of SDSS, we display the gri bands as blue, green, and red channels. The extent of all images is 3 times the D25 size of the galaxy. The print figure only presents two galaxies of each XUV-disk variety, as a guide to content. NGC 772 and NGC 4254 (M99) are shown as examples of Type 1, UGC 10445 and NGC 7418A for mixed-type objects, and NGC 2090 and NGC 2541 for Type 2 XUV-disks. [See the electronic edition of the Supplement for complete set of Figs. 16.1-16.54.]

Мне кажется, что центральная яркая область довольно большая, порядка 10', но точно не понятно.


In [87]:
Image('large-fg16_19_dist.png', width=500)


Out[87]:

In [88]:
def plot_SF(ax):
    ax.plot([0., 86./2/(175./600.)], [0., 0.], '-', lw=7., color='b')
#     ax.plot([0., 123./2/(175./600.)], [0., 0.], '-', lw=7., color='midnightblue') # глазами видно, что там больше, но там именно спирали маленькие
    ax.plot([0., 150*58./180.], [0., 0.], '-', lw=7., color='r')
    ax.plot([250./2/(175./600.), 260./2/(175./600.)], [0., 0.], '-', lw=7., color='b') #внешняя спираль
    ax.plot([220./2/(175./600.), 310./2/(175./600.)], [0., 0.], '-', lw=7., color='b') #внешняя спираль, на глаз
    
plot_SF(plt.gca())
plt.xlim(0, 650)
plt.ylim(0, 200)


Out[88]:
(0, 200)

Неустойчивость

Одножидкостная

Устойчиво, когда > 1: $$Q_g = \frac{\Sigma_g^{cr}}{\Sigma_g}=\frac{\kappa c_g}{\pi G \Sigma_g}$$ $$Q_s = \frac{\Sigma_s^{cr}}{\Sigma_s}=\frac{\sigma_R}{\sigma_R^{min}}=\frac{\kappa \sigma_R}{3.36 G \Sigma_s}$$


In [89]:
sound_vel = 6.  #скорость звука в газе, км/с
data_lim = max(r_sig_ma) #где заканчиваются данные

In [90]:
fig = plt.figure(figsize=[12, 6])
gd_data = zip(r_g_dens, gas_dens)
#кроме первой точки, т.к. там деление на ноль
plt.plot(r_g_dens, [1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
                    zip([epicyclicFreq_real(gas_approx, x, scale) for x in r_g_dens], gas_dens)], 's-', label='$Q_{gas}$')
plt.plot(r_g_dens, [1./Qg(epicycl=l[0], sound_vel=4., gas_density=l[1]) for l in 
                    zip([epicyclicFreq_real(gas_approx, x, scale) for x in r_g_dens], gas_dens)], 's-', label='$Q_{gas}$ & c=4')

plt.plot(r_g_dens, [1./Qs(epicycl=l[0], sigma=l[1], star_density=l[2]) for l in 
                    zip([epicyclicFreq_real(gas_approx, x, scale) for x in r_g_dens],
                        map(sig_R_maj_max, r_g_dens), 
                        [surf_density(l_, M_to_L_I, 'I') for l_ in [mu_disc(ll, mu0=mu0d_I, h=h_disc_I) for ll in r_g_dens]])], 's-', label='$Q_{star}^{max}$')

plt.plot(r_g_dens, [1./Qs(epicycl=l[0], sigma=l[1], star_density=l[2]) for l in 
                    zip([epicyclicFreq_real(gas_approx, x, scale) for x in r_g_dens],
                        map(sig_R_maj_min, r_g_dens), 
                        [surf_density(l_, M_to_L_I, 'I') for l_ in [mu_disc(ll, mu0=mu0d_I, h=h_disc_I) for ll in r_g_dens]])], 's-', label='$Q_{star}^{min}$')

plt.axhline(y=1, ls='--')
plt.legend()
plot_SF(plt.gca())
plt.ylabel('$Q^{-1}$', fontsize=15)
plt.xlim(0., 550);


Видно, что в центре с кучей газа неустойчивость, но эффект быстро спадает.

НЕ ИСПРАВЛЕНО ЗА 1.6! И правильно, и не надо.

Для внешней спирали что-то видно, давайте сохраним картинку:


In [91]:
fig = plt.figure(figsize=[12, 6])

plt.plot(r_HI_dens, [1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
                    zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], HI_dens)], 's-', label=r'$\rm{HI}$')
plt.plot(r_mol_dens, [1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
                    zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], mol_dens)], 's-', label=r'$\rm{H_2}$')
plt.plot(r_g_dens, [1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
                    zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], gas_dens)], 's-', label=r'$total$')
plt.plot(r_g_dens, [1./Qg(epicycl=l[0], sound_vel=11., gas_density=l[1]) for l in 
                    zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], gas_dens)], 's-', label=r'$total\: &\: c=11$')

plt.axhline(y=1, ls='--')
plt.legend()
plot_SF(plt.gca())
plt.ylabel('$Q^{-1}$', fontsize=15)
plt.title(name)
for q_ in [1., 1.5, 2., 3.]:
    plt.axhline(y=1./q_, lw=10, alpha=0.15, color='grey')
plt.grid()
plt.ylim(0, 1.2)
plt.savefig('..\\..\pics\\instab_spirals\\'+name+'_spiral'+'.png', format='png', bbox_inches='tight');


Двухжидкостная

Кинетическое приближение: $$\frac{1}{Q_{\mathrm{eff}}}=\frac{2}{Q_{\mathrm{s}}}\frac{1}{\bar{k}}\left[1-e^{-\bar{k}^{2}}I_{0}(\bar{k}^{2})\right]+\frac{2}{Q_{\mathrm{g}}}s\frac{\bar{k}}{1+\bar{k}^{2}s^{2}}>1\,$$

Гидродинамическое приближение: $$\frac{2\,\pi\, G\, k\,\Sigma_{\mathrm{s}}}{\kappa+k^{2}\sigma_{\mathrm{s}}}+\frac{2\,\pi\, G\, k\,\Sigma_{\mathrm{g}}}{\kappa+k^{2}c_{\mathrm{g}}}>1$$ или $$\frac{1}{Q_{\mathrm{eff}}}=\frac{2}{Q_{\mathrm{s}}}\frac{\bar{k}}{1+\bar{k}^{2}}+\frac{2}{Q_{\mathrm{g}}}s\frac{\bar{k}}{1+\bar{k}^{2}s^{2}}>1$$ для безразмерного волнового числа ${\displaystyle \bar{k}\equiv\frac{k\,\sigma_{\mathrm{s}}}{\kappa}},\, s=c/\sigma$


In [92]:
total_gas_data = zip(r_g_dens, map(lambda l: l, gas_dens))[:20]
disk_scales = [(l[5], l[0].split(' ')[1]) for l in all_photometry]


fig = plt.figure(figsize=[10, 6])
ax = plt.gca()

plot_2f_vs_1f(ax=ax, total_gas_data=total_gas_data, epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu_disc(l, mu0=mu0d_J, h=h_disc_J), M_to_L_J, 'J'), 
              star_density_min=lambda l: surf_density(mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L_I, 'I'), 
              data_lim=data_lim, color='g', alpha=0.3, disk_scales=disk_scales, label='J/I maj max/min')

plot_2f_vs_1f(ax=ax, total_gas_data=total_gas_data, epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L_I, 'I'), 
              star_density_min=lambda l: surf_density(mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L_I, 'I'), 
              data_lim=data_lim, color='m', alpha=0.3, disk_scales=disk_scales, label='I maj max/min')

plot_2f_vs_1f(ax=ax, total_gas_data=total_gas_data, epicycl=epicyclicFreq_real, 
                  gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
                  sigma_max=sig_R_maj_max, 
                  sigma_min=sig_R_maj_min, 
                  star_density_max=lambda l: surf_density(mu_disc(l, mu0=mu0d_V, h=h_disc_V), M_to_L_V, 'V'), 
                  star_density_min=lambda l: surf_density(mu_disc(l, mu0=mu0d_V, h=h_disc_V), M_to_L_V, 'V'), 
                  data_lim=data_lim, color='r', alpha=0.2, disk_scales=disk_scales, label='V maj max/min')

plt.ylim(0., 2.5)
plt.axhline(y=1., ls='-', color='grey')
plot_SF(ax)
plt.grid()
plt.xlim(0., 265.);


Что интересно - держится на субмаржинальном уровне достаточно далеко.

Что насчет третьей точки, почему она оказывается ниже?


In [93]:
gas_data = zip(r_g_dens, gas_dens)[:7]
invQg, invQs, invQeff = zip(*get_invQeff_from_data(gas_data=gas_data, 
                                epicycl=epicyclicFreq_real, 
                                gas_approx=spl_gas,
                                sound_vel=sound_vel, 
                                scale=scale,
                                sigma=sig_R_maj_min,
                                star_density=lambda l: surf_density(mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L_I, 'I'), verbose=True))


r = 10.95; gas_d = 179.72; epicycl = 684.51; sig = 121.23; star_d = 757.93
	Qs = 8.07; Qg = 1.68; Qeff = 1.65
r = 31.75; gas_d = 95.41; epicycl = 200.55; sig = 108.23; star_d = 572.72
	Qs = 2.79; Qg = 0.93; Qeff = 0.90
r = 50.36; gas_d = 37.20; epicycl = 128.78; sig = 89.51; star_d = 445.73
	Qs = 1.91; Qg = 1.53; Qeff = 1.38
r = 70.07; gas_d = 17.92; epicycl = 61.78; sig = 82.71; star_d = 341.82
	Qs = 1.10; Qg = 1.52; Qeff = 0.94
r = 89.78; gas_d = 15.48; epicycl = 83.73; sig = 82.71; star_d = 262.13
	Qs = 1.95; Qg = 2.39; Qeff = 1.64
r = 109.48; gas_d = 11.01; epicycl = 85.02; sig = 82.71; star_d = 201.02
	Qs = 2.58; Qg = 3.41; Qeff = 2.19
r = 129.19; gas_d = 11.57; epicycl = 67.26; sig = 82.71; star_d = 154.15
	Qs = 2.66; Qg = 2.57; Qeff = 2.17

Похоже на то, что основная причина - в стремительном падении плотности газа.

End


In [94]:
from matplotlib.animation import FuncAnimation

total_gas_data = zip(r_g_dens, map(lambda l: l, gas_dens))[:20]

fig = plt.gcf()
plt.figure(figsize=(10,6))

ax = plt.gca()

def animate(i):
    ax.cla()
    plot_2f_vs_1f(ax=ax, total_gas_data=total_gas_data, epicycl=epicyclicFreq_real, gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=all_photometry[i][-1], 
              star_density_min=all_photometry[i][-1],
              data_lim=data_lim, color=np.random.rand(3), alpha=0.3, disk_scales=[(all_photometry[i][5], '')])
    ax.axhline(y=1., ls='-', color='grey')
    ax.set_title(all_photometry[i][0])
    ax.set_ylim(0., 2.5)
    ax.set_xlim(0., 265.)
    return ax
anim = FuncAnimation(plt.gcf(), animate, frames=len(all_photometry), interval=1000)


C:\Anaconda\lib\site-packages\matplotlib\axes\_axes.py:545: UserWarning: No labelled objects found. Use label='...' kwarg on individual plots.
  warnings.warn("No labelled objects found. "
<matplotlib.figure.Figure at 0x1119a6d8>

In [95]:
# anim.save('..\\..\pics\\'+name+'.gif', writer='imagemagick', fps=1)

In [96]:
# from IPython.display import HTML
# HTML(anim.to_html5_video())

Самый максимальный диск

Существует ограничение на максимальный диск в ~0.85 (изотермическое гало) и на субмаксимальный в 0.55-0.6 (NFW гало). Попробуем дотянуть фотметрию до максимальных дисков и посмотрим, как изменятся M/L (скорость зависит как корень из M/L):


In [97]:
fig = plt.figure(figsize=[14,6])

plt.plot(test_points, spl_gas(test_points), '-', label='spline')
plt.plot(test_points, 0.85*spl_gas(test_points), '--', label='max disc')
# plt.plot(test_points, 0.6*spl_gas(test_points), '--', label='submax disc')
# plt.errorbar(r_wsrt, vel_wsrt, yerr=e_vel_wsrt, fmt='.', marker='.', mew=0, label = 'WSRT')
# plt.plot(r, vel, '.', label = 'Noord thesis')
plt.plot(_1, _2, '.', label='CO+HI')

max_coeffs = {}

for ind, photom in enumerate(all_photometry):
    if type(photom[5]) == tuple:
        disc_v = lambda l: disc_vel(l, photom[7][0](0), photom[5][0], scale, Sigma0_2=photom[7][1](0), h_2=photom[5][1])
    else:
        disc_v = lambda l: disc_vel(l, photom[7](0), photom[5], scale)
    
    max_coeff = 100.
    submax_coeff = 100.
    for d1, d2 in zip(_1, _2)[20:]:
        max_coeff = min(0.85*d2/disc_v(d1), max_coeff)
        submax_coeff = min(0.6*d2/disc_v(d1), submax_coeff)
        
              
#     values = map(disc_v, test_points[1:])
#     disc_max = test_points[values.index(max(values))]
        
#     max_coeff = 0.85*spl_gas(disc_max)/disc_v(disc_max)
#     submax_coeff = 0.6*spl_gas(disc_max)/disc_v(disc_max)
    
    plt.plot(test_points, map(lambda l: disc_vel(l, max_coeff**2 * photom[7](0), photom[5], scale), test_points), next(linecycler), label=photom[0] + '_MAX')
    
    print '{:25s}: M/L was {:2.2f} and for max it equal {:2.2f}, for submax equal {:2.2f}'.format(photom[0], photom[6], photom[6]*max_coeff**2, photom[6]*submax_coeff**2)
    max_coeffs[photom[0]] = [max_coeff**2, submax_coeff**2]


plt.ylim(0, 300)
plt.xlim(0, 500)
plt.legend(bbox_to_anchor=(1.15, 1.0));


YOSHINO I                : M/L was 0.97 and for max it equal 1.00, for submax equal 0.50
YOSHINO V                : M/L was 1.74 and for max it equal 1.48, for submax equal 0.74
YOSHINO J                : M/L was 0.95 and for max it equal 0.63, for submax equal 0.32
SPITZER 3.6              : M/L was 0.65 and for max it equal 0.38, for submax equal 0.19
SPITZER 3.6 faceon       : M/L was 0.65 and for max it equal 0.91, for submax equal 0.45
GALFIT K                 : M/L was 0.79 and for max it equal 0.56, for submax equal 0.28
S4G 3.6                  : M/L was 0.65 and for max it equal 0.88, for submax equal 0.44

Немного криво, но и так в принципе видно, что S4G и K не подходят, для J нет тупо точек.


In [98]:
from matplotlib.animation import FuncAnimation

fig = plt.gcf()
plt.figure(figsize=(10,6))

ax = plt.gca()

def animate(i):
    ax.cla()
       
    plot_2f_vs_1f(ax=ax, total_gas_data=total_gas_data,
              epicycl=epicyclicFreq_real, gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: max_coeffs[all_photometry[i][0]][0]*all_photometry[i][-1](l), 
              star_density_min=lambda l: max_coeffs[all_photometry[i][0]][0]*all_photometry[i][-1](l),
              data_lim=data_lim, color=np.random.rand(3), alpha=0.2, disk_scales=[(all_photometry[i][5], '')])
    
    plot_2f_vs_1f(ax=ax, total_gas_data=total_gas_data, 
              epicycl=epicyclicFreq_real, gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: max_coeffs[all_photometry[i][0]][1]*all_photometry[i][-1](l), 
              star_density_min=lambda l: max_coeffs[all_photometry[i][0]][1]*all_photometry[i][-1](l),
              data_lim=data_lim, color=np.random.rand(3), alpha=0.2, disk_scales=[(all_photometry[i][5], '')])
    
    ax.axhline(y=1., ls='-', color='grey')
    ax.set_title(all_photometry[i][0])
    ax.set_ylim(0., 2.5)
    ax.set_xlim(0., 160.)
    plot_SF(ax)
    return ax
anim = FuncAnimation(plt.gcf(), animate, frames=len(all_photometry), interval=1000)


<matplotlib.figure.Figure at 0x10cd3b38>

In [99]:
# anim.save('..\\..\pics\\'+name+'_MAXDISCS.gif', writer='imagemagick', fps=1)

In [100]:
# from IPython.display import HTML
# HTML(anim.to_html5_video())

Есть очень неплохие модели.

Картинка


In [101]:
summary_imgs_path = '..\\..\pics\\notebook_summary\\'

def save_model_plot(path):
    fig, axes = plt.subplots(1, 5, figsize=[40,7])
    fig.tight_layout()
    
    axes[0].imshow(ImagePIL.open('n4258_SDSS_labeled.jpg'), aspect='auto')
    axes[0].set_title(name)
    
    try:
        axes[1].errorbar(r_sig_ma, sig_ma, yerr=e_sig_ma, fmt='.', marker='.', mew=0, color='red', label='$\sigma_{los}^{maj}$')
        axes[1].plot(points, map(sig_R_maj_min, points))
        axes[1].plot(points, map(sig_R_maj_max, points))
        axes[1].plot(points, map(sig_R_maj_maxmaxtrue, points))
    except Exception:
        pass
    
    try:
        axes[1].errorbar(r_sig_mi, sig_mi, yerr=e_sig_mi, fmt='.', marker='.', mew=0, color='red', label='$\sigma_{los}^{min}$')
        axes[1].plot(points, map(sig_R_minor_min, points), '--')
        axes[1].plot(points, map(sig_R_minor_max, points), '--')
    except Exception:
        pass

    axes[1].set_ylim(0,250)
    axes[1].set_xlim(0, 105)  
    axes[1].grid()
    axes[1].legend()
    axes[1].set_title('Dispersions')
    
    for photom in all_photometry:
        axes[2].plot(r_g_dens, map(photom[-1], r_g_dens), '-', label='{} [M/L={:2.2f}]'.format(photom[0], photom[-2]))
    axes[2].set_xlim(0, 150)
    axes[2].set_ylim(0, 300)
    axes[2].set_title('Photometry')
    axes[2].grid()
    axes[2].legend(loc='lower left')
    
    axes[3].plot(r_HI_dens, HI_dens, '--', label='HI')
    axes[3].plot(zip(*total_gas_data)[0], zip(*total_gas_data)[1], '*-')
    axes[3].plot(r_mol_dens, mol_dens, '--', label='mol')
    axes[3].set_title('Gas')
    axes[3].grid()
    axes[3].set_xlim(0, 200)
    axes[3].legend()
       
    #change this
    @save_model(models_path+'n4258_modelImax.npy')
    def plot_2f_vs_1f_(*args, **kwargs):
        plot_2f_vs_1f(*args, **kwargs)
    plot_2f_vs_1f_(ax=axes[4], total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              data_lim=data_lim, color='g', alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc',
              ML = 1.00,
              CO = lambda l: y_interp_(l))
    
    @save_model(models_path+'n4258_model36max.npy')
    def plot_2f_vs_1f_(*args, **kwargs):
        plot_2f_vs_1f(*args, **kwargs)
    plot_2f_vs_1f_(ax=axes[4], total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=0.38), 
              star_density_min=lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=0.38), 
              data_lim=data_lim, color='m', alpha=0.2, disk_scales=disk_scales, label='SPITZER 3.6 maxdisc',
              ML = 0.38,
              CO = lambda l: y_interp_(l))


    axes[4].set_ylim(0., 2.5)
    axes[4].set_xlim(0., 130.)
    axes[4].axhline(y=1., ls='-', color='grey')
    plot_SF(axes[4])
    axes[4].grid()
    axes[4].set_title('Instability')
    axes[4].text(10., 2.2, '+S, +M(~170)', fontsize=25., color='b')
       
    plt.savefig(path+name+'.png', format='png', bbox_inches='tight');
    
save_model_plot(summary_imgs_path)


Другие механизмы

Schaye (2004), 'cold gas phase': $$\Sigma_g > 6.1 f_g^{0.3} Z^{-0.3} I^{0.23}$$ или при constant metallicity of 0.1 $Z_{sun}$ and interstellar flux of ionizing photons 10^6 cm−2 s−1: $$\Sigma_g > 6.1 \frac{\Sigma_g}{\Sigma_g + \Sigma_s}$$


In [92]:
plt.plot(zip(*total_gas_data)[0], zip(*total_gas_data)[1], 'o-')

for photom in all_photometry:
    dens_s04 = [Sigma_crit_S04(l[0], l[1], photom[7]) for l in total_gas_data]
    plt.plot(zip(*total_gas_data)[0], dens_s04, '--', label=photom[0])

plt.legend()
plt.ylim(0, 50.);


Видимо везде неустойчиво.

Hunter et al (1998), 'competition with shear' according to Leroy: $$\Sigma_A = \alpha_A\frac{\sigma_g A}{\pi G}$$


In [93]:
fig, (ax1, ax2) = plt.subplots(1,2,figsize=[16, 5])
ax1.plot(test_points, [oort_a(x, gas_approx) for x in test_points], '-', label='poly')
ax1.plot(test_points, [oort_a(x, spl_gas) for x in test_points], '-', label='spline')
ax1.set_xlabel('$R, arcsec$')
ax1.set_ylabel('$d\Omega/dr$', fontsize=15)
ax1.legend()

dens_A = [Sigma_crit_A(l, spl_gas, 2., 6.) for l in zip(*total_gas_data)[0]]
ax2.plot(zip(*total_gas_data)[0], dens_A, '--')
ax2.plot(zip(*total_gas_data)[0], zip(*total_gas_data)[1], 'o-')
ax2.set_ylim(0, 50.);


Непонятно, судя по всему тоже везде неустойчиво.

Отношение водорода к молекулярному газу

Из https://ui.adsabs.harvard.edu/#abs/2016MNRAS.460.1106W/abstract: два возможных вида связи между молекулярным и атомарным газом $R_{mol} = \Sigma_{H_2}/\Sigma_{HI}$:

$$R_{mol} = \Sigma_{star}/81$$

или $$R_{mol} = \left(\frac{P_h}{1.7 \times 10^4 cm^{-3}K k_B } \right)^{0.8},\, P_h = \frac{\pi}{2}G\Sigma_g(\Sigma_g + \frac{\sigma_g}{\sigma_z}\Sigma_{star})$$


In [94]:
def R1(Sigma_star):
    return Sigma_star/81.

def h2_gas(r, h_gas_dens):
    return R1(star_density(r))*h_gas_dens

star_density=lambda l: surf_density(mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L_I, 'I')

plt.plot(r_g_dens, gas_dens, 's-', color='b')
plt.plot(r_g_dens, [h2_gas(_[0], _[1]) for _ in  zip(r_g_dens, gas_dens)], 's-', color='r');


Вторая оценка - малой оси у нас нет и придется вытаскивать из большой:


In [95]:
@flat_end(sig_maj_lim)
def sig_R_maj_true(r, alpha, spl_maj=spl_maj):
    return spl_maj(r)/sqrt(sigPhi_to_sigR_real(r)*sin_i**2 + alpha**2 * cos_i**2)

@flat_end(sig_maj_lim)
def sig_z(r, alpha, spl_maj=spl_maj):
    return sig_R_maj_true(r, alpha, spl_maj=spl_maj)*alpha

plt.plot(points, map(lambda l: sig_z(l, 0.3), points), label = '0.3')
plt.plot(points, map(lambda l: sig_z(l, 0.5), points), label = '0.5')
plt.plot(points, map(lambda l: sig_z(l, 0.7), points), label = '0.7')

plt.legend()
plt.ylim(0,200)
plt.xlim(0,100);



In [96]:
def R2(r, h_gas_dens, alpha, sound_vel):
    G = 6.67408
    kB = 3.7529917
    Ph = np.pi/2. * G * h_gas_dens * (h_gas_dens + sound_vel/sig_z(r, alpha) * star_density(r))
    return np.power(4.363474*Ph/(1.7 * 10000. * kB) , 0.8)

def h2_gas2(r, h_gas_dens, alpha, sound_vel):
    return R2(r, h_gas_dens, alpha, sound_vel)*h_gas_dens

plt.plot(r_g_dens[:4], [R2(_[0], _[1], 0.3, 6.) for _ in  zip(r_g_dens, gas_dens)[:4]], 's-')
plt.plot(r_g_dens[:4], [R2(_[0], _[1], 0.5, 6.) for _ in  zip(r_g_dens, gas_dens)[:4]], 's-')
plt.plot(r_g_dens[:4], [R2(_[0], _[1], 0.7, 6.) for _ in  zip(r_g_dens, gas_dens)[:4]], 's-');


И теперь сравнение с настоящим значением:


In [97]:
fig = plt.figure(figsize=[10, 10])

# plt.plot(r_g_dens, gas_dens, 's-', color='b')
plt.semilogy(r_g_dens, [h2_gas2(_[0], _[1], 0.3, 6.) for _ in  zip(r_g_dens, gas_dens)], '-', label='0.3')
plt.semilogy(r_g_dens, [h2_gas2(_[0], _[1], 0.5, 6.) for _ in  zip(r_g_dens, gas_dens)], '-', label='0.5')
plt.semilogy(r_g_dens, [h2_gas2(_[0], _[1], 0.7, 6.) for _ in  zip(r_g_dens, gas_dens)], '-', label='0.7')

plt.semilogy(r_g_dens, map(lambda l: 0.44*l, gas_dens), '-', color='m', label='x0.44')
plt.semilogy(r_mol_dens, mol_dens, 'o-', color='r')

plt.semilogy(r_g_dens, [h2_gas(_[0], _[1]) for _ in  zip(r_g_dens, gas_dens)], '-', label='/81')

plt.legend()
plt.ylim(1., 10000.)
plt.xlim(0, 100);


Видно, что He_coeff лучше всего описывает наблюдения.

(надо учесть, что здесь может быть ошибка и относиться с острожностью, например неверно взяты значения атомарного газа - может быть там не убран гелий и т.д.)

Дисперсии из АD

Интересный вариант для тех галактик, в которых есть данные по газу. Разница между скоростями вращения звезд и газа вокруг центра галактики называется ассиметричным сдвигом и описывается следующим уравнением (Binney & Tremaine 1987): $$v_{\mathrm{c}}^{2}-\bar{v}_{\varphi}^{2}=\sigma_{R}^{2}\left(\frac{\sigma_{\varphi}^{2}}{\sigma_{R}^{2}}-1-\frac{\partial\ln\Sigma_{\mathrm{s}}}{\partial\ln R}-\frac{\partial\ln\sigma_{R}^{2}}{\partial\ln R}\right)\,$$ Отношение ${\displaystyle \frac{\sigma_{\varphi}^{2}}{\sigma_{R}^{2}}}$ знаем из соответствующего уравнения. Поймем, как в этом выражении вычисляется логарифмическая производная ${\displaystyle \frac{\partial\ln\Sigma_{\mathrm{s}}}{\partial\ln R}}$. Если отношение массы к светимости принять постоянной вдоль радиуса величиной, то в производной ${\displaystyle \frac{\partial\ln\Sigma_{\mathrm{s}}}{\partial\ln R}}$ можно использовать поверхностную яркость звездного диска вместо поверхностной плотности $\Sigma_{\mathrm{s}}$ в тех полосах, которые трассируют старое звездное население. Это означает, что логарифмическая производная должна быть заменена отношением $-{\displaystyle \frac{R}{h_{\text{d}}}}\,,$ где $h_{\text{d}}$ --- экспоненциальный масштаб диска. Вычисление $\frac{\partial\ln\sigma_{R}^{2}}{\partial\ln R}$ из кинематического масштаба равно $-\frac{2R}{h_{kin}}$


In [98]:
def sigR2Evaluation(R, h, h_kin, p_star, p_gas):
    '''Вычисление sigmaR^2 в случае, если уже известен кинетический масштаб.'''
    return (p_gas(R) ** 2 - p_star(R) ** 2 ) / ( sigPhi_to_sigR_real(R) - 1 + R / h + R / h_kin )

def asymmetricDriftEvaluation(r_pc, h, path, p_star, p_gas, upperLimit):
    '''Вычисление ассиметричного сдвига на основе формулы (21) из методички. Логарифмическая производная от радиальной
     дисперсии скоростей считается как предложено в статье Silchenko et al. 2011, экспонентой фитируется для R > 1h.
     Сами значения считаются только для тех точек, есть данные и по газу и по звездам.'''
    eps = 0.1
    h_kin = 0
    h_kin_next = h
    sigR2 = []
    upper = upperLimit
    r_gt_1h = filter(lambda x: x > h and x <= upper, r_pc)
    expfit = poly1d(1)

    h_disc = h

    print '#!!!!!!!!!!!!# Asymmetric drift evaluation procedure with eps = ' + str(eps) + ' starts.'
    while(abs(h_kin - h_kin_next) > eps):
        h_kin = h_kin_next
        sigR2[:] = []
        for R in r_gt_1h:
            sigR2.append((p_gas(R) ** 2 - p_star(R) ** 2 ) / ( sigPhi_to_sigR_real(R) - 1 + R / h + R / h_kin ))
        sigR2 = map(math.log, sigR2)
        expfit = poly1d(polyfit(r_gt_1h, sigR2, deg=1))
        h_kin_next = (-1 / expfit.coeffs[0])
        print '#!!!!!!!!!!!!# Next approx h_kin =', h_kin_next

    h_kin = h_kin_next
    sigR2[:] = []
    for R in r_pc:
        sigR2.append((p_gas(R) ** 2 - p_star(R) ** 2 ) / ( sigPhi_to_sigR_real(R) - 1 + R / h + R / h_kin ))

    sigR20 = math.exp(expfit.coeffs[1])
#     rexp_sigR2 = evalStartExp(r_pc, sigR2, lambda x: sigR20 * math.exp(-x / h_kin))
    return sigR20, h_kin, [sigR2Evaluation(R, h, h_kin, p_star, p_gas) for R in r_pc]

sigR20, h_kin, sigR2 = asymmetricDriftEvaluation(r_sig_ma, 40., '', star_approx, spl_gas, sig_maj_lim)


#!!!!!!!!!!!!# Asymmetric drift evaluation procedure with eps = 0.1 starts.
#!!!!!!!!!!!!# Next approx h_kin = 24.90140622
#!!!!!!!!!!!!# Next approx h_kin = 24.5641332611
#!!!!!!!!!!!!# Next approx h_kin = 24.5549475066

In [99]:
import scipy.interpolate
fig = plt.figure(figsize=[10, 7])

plt.plot(points, map(sig_R_maj_minmin, points), label = 'maj minmin')
plt.plot(points, map(sig_R_maj_min, points), label = 'maj min')
plt.plot(points, map(sig_R_maj_max, points), label = 'maj max')
plt.plot(points, map(sig_R_maj_maxmax, points), label = 'maj maxmax')
plt.plot(points, map(sig_R_maj_maxmaxtrue, points), label = 'maj maxmaxtrue')

plt.plot(r_sig_ma, np.sqrt(sigR2), 'o')
plt.plot(points, map(lambda l: np.sqrt(sigR20 * math.exp(-l / h_kin)), points),  '--', alpha=0.5)

ad_interp = scipy.interpolate.interp1d(r_sig_ma, np.sqrt(sigR2))

@flat_end(sig_maj_lim)
def ad_interp_(r):
    return ad_interp(r)

plt.plot(points[2:], map(ad_interp_, points[2:]),  '--', alpha=0.5)

plt.legend()
plt.ylim(0,450)
plt.xlim(0,100);


Довольно неплохо кстати.


In [100]:
fig = plt.figure(figsize=[10, 6])
ax = plt.gca()

plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[:15], epicycl=epicyclicFreq_real, 
          gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
          sigma_max=ad_interp_, 
          sigma_min=ad_interp_, 
          star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
          star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
          data_lim=data_lim, color='g', alpha=0.3, disk_scales=disk_scales, label='I Yoshino maxdisc AD')


plt.ylim(0., 2.5)
plt.axhline(y=1., ls='-', color='grey')
plot_SF(ax)
plt.grid()
plt.xlim(0., 250);


Если брать экспонентой:


In [101]:
fig = plt.figure(figsize=[10, 6])
ax = plt.gca()

plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[:15], epicycl=epicyclicFreq_real, 
          gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
          sigma_max=lambda l: np.sqrt(sigR20 * math.exp(-l / h_kin)), 
          sigma_min=lambda l: np.sqrt(sigR20 * math.exp(-l / h_kin)), 
          star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
          star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
          data_lim=data_lim, color='g', alpha=0.3, disk_scales=disk_scales, label='I Yoshino maxdisc AD')

plt.xlim(0., 300.)
plt.ylim(0., 2.5)
plt.axhline(y=1., ls='-', color='grey')
plot_SF(ax)
plt.grid();


Наклон слишком велик.

Экспоненциальные оценки H2

В работах van der Hulst (2016) и Bigiel, Blitz (2012) есть экспоненциальные соотношения для H2+HI (см. заметки).

Можно попробовать использовать это для оценки молекулярной компоненты газа:


In [102]:
# r25 = h_disc_B*(25. - mu0d_B)/1.0857
# r25, h_disc_B, (25. - mu0d_B)/1.0857

r25 = 2.8*40.
r25


Out[102]:
112.0

In [103]:
from scipy.optimize import curve_fit

def func1(x, a):
    return a * np.exp(-1.95 * x/r25)

def func2(x, a):
    return a * np.exp(-1.65 * x/r25)

popt, pcov = curve_fit(func1, r_HI_dens[20:], HI_dens[20:])
points_ = np.linspace(100., max(r_g_dens), 100.)
plt.plot(points_, func1(points_, *popt), '--', alpha=0.3)

popt, pcov = curve_fit(func2, r_HI_dens[20:], HI_dens[20:])
points_ = np.linspace(100., max(r_g_dens), 100.)
plt.plot(points_, func2(points_, *popt), '--', alpha=0.3)

for i in range(int(max(r_g_dens)/r25)+1):
    if i%2 == 0:
        plt.axvspan(i*r25, (i+1)*r25, color='grey', alpha=0.1)

plt.plot(r_g_dens, gas_dens, 's-')
plt.plot(r_HI_dens, HI_dens, 's-')
plt.ylim(0., 40.);


C:\Anaconda\lib\site-packages\ipykernel\__main__.py:10: DeprecationWarning: object of type <type 'float'> cannot be safely interpreted as an integer.
C:\Anaconda\lib\site-packages\ipykernel\__main__.py:14: DeprecationWarning: object of type <type 'float'> cannot be safely interpreted as an integer.

In [104]:
def func(x, a, b):
    return a * np.exp(-b * x/r25)

popt, pcov = curve_fit(func, r_HI_dens[7:], HI_dens[7:])
print popt[1]
points_ = np.linspace(100., max(r_g_dens), 100.)
plt.plot(points_, func(points_, *popt), '--', alpha=0.3)

for i in range(int(max(r_g_dens)/r25)+1):
    if i%2 == 0:
        plt.axvspan(i*r25, (i+1)*r25, color='grey', alpha=0.1)

plt.plot(r_g_dens, gas_dens, 's-')
plt.plot(r_HI_dens, HI_dens, 's-')
plt.ylim(0., 20.);


0.274483210019
C:\Anaconda\lib\site-packages\ipykernel\__main__.py:6: DeprecationWarning: object of type <type 'float'> cannot be safely interpreted as an integer.

In [105]:
def func(x, a, b):
    return a * np.exp(-b * x/r25)

for i in range(15, len(r_HI_dens)-5, 3):
    popt, pcov = curve_fit(func, r_HI_dens[i:], HI_dens[i:])
    print popt[1]
    points_ = np.linspace(1., max(r_g_dens), 100.)
    plt.plot(points_, func(points_, *popt), '--', alpha=0.3)

for i in range(int(max(r_g_dens)/r25)+1):
    if i%2 == 0:
        plt.axvspan(i*r25, (i+1)*r25, color='grey', alpha=0.1)

plt.plot(r_g_dens, gas_dens, 's-')
plt.plot(r_HI_dens, HI_dens, 's-')
plt.ylim(0., 20.);


0.393936913332
0.522328182807
0.704234637607
0.928181569312
1.21779213928
1.03169452185
0.909573138556
0.844873384726
0.640635142398
0.794899602769
C:\Anaconda\lib\site-packages\ipykernel\__main__.py:7: DeprecationWarning: object of type <type 'float'> cannot be safely interpreted as an integer.

Сравнение с Romeo Falstad 2013


In [106]:
# import scipy.interpolate

# y_interp = scipy.interpolate.interp1d(list(r_mol_dens), list(mol_dens))

# def y_interp_(r):
#     if r <= min(r_mol_dens):
#         return y_interp(min(r_mol_dens))
#     elif r < max(r_mol_dens):
#         return y_interp(r)
#     else:
#         return 0.

Тут учитывается толщина диска:


In [424]:
plot_RF13_vs_2F(r_g_dens=r_HI_dens[1:14], HI_gas_dens=HI_dens[1:14], CO_gas_dens=[y_interp_(l) for l in r_HI_dens][1:14], 
                epicycl=epicyclicFreq_real, sound_vel=sound_vel, sigma_R_max=sig_R_maj_max, sigma_R_min=sig_R_maj_min,  
                star_density=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
                alpha_max=0.7, alpha_min=0.3, scale=scale, gas_approx=spl_gas, thin=False)


А тут нет:


In [423]:
plot_RF13_vs_2F(r_g_dens=r_HI_dens[1:14], HI_gas_dens=HI_dens[1:14], CO_gas_dens=[y_interp_(l) for l in r_HI_dens][1:14], 
                epicycl=epicyclicFreq_real, sound_vel=sound_vel, sigma_R_max=sig_R_maj_max, sigma_R_min=sig_R_maj_min,  
                star_density=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
                alpha_max=0.7, alpha_min=0.3, scale=scale, gas_approx=spl_gas, thin=True)
plt.savefig('..\\..\pics\\RF13\\'+name+'.png', format='png', bbox_inches='tight');


Видно, что согласие достаточно хорошее.

Влияние параметров на результат

Влияние скорости звука:


In [442]:
%%time

r25_ = h_disc_I*(25. - mu0d_I)/1.0857
plot_2f_vs_1f(ax=plt.gca(), total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, 
              sound_vel=[50*np.exp(-2*l/r25_) if l < r25_ else 50*np.exp(-2.) for l in r_g_dens[1:]], 
              scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              data_lim=data_lim, color='m', alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc')

plot_param_depend(ax=plt.gca(), data_lim=data_lim, color='g', alpha=0.3, disk_scales=disk_scales, label='I maxdisc', N = 20,
                  total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], 
                  epicycl=epicyclicFreq_real, 
                  gas_approx=spl_gas, 
                  sound_vel=list(np.linspace(4., 15., 20)), 
                  scale=scale, 
                  sigma_max=sig_R_maj_max, 
                  sigma_min=sig_R_maj_min, 
                  star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
                  star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'))

plt.savefig('..\\..\pics\\cg\\'+name+'.png', format='png', bbox_inches='tight');


Wall time: 7min 42s

Замена снятых точек на сумму молек. и атомарного газа:


In [426]:
fig = plt.figure(figsize=[14, 5])
ax = plt.gca()

plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              data_lim=data_lim, color='g', alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc')

plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_HI_dens, [He_coeff*(y_interp_(l[0]) + l[1]) for l in zip(r_HI_dens, HI_dens)])[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              data_lim=data_lim, color='m', alpha=0.15, disk_scales=disk_scales, label='I Yoshino maxdisc CO+HI')


ax.set_ylim(0., 2.5)
ax.set_xlim(0., 130.)
ax.axhline(y=1., ls='-', color='grey')
plot_SF(ax)
ax.grid()


Влияние убирания молек. газа:


In [427]:
ax = plt.gca()
plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              data_lim=data_lim, color='g', alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc')

plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_HI_dens, map(lambda l: He_coeff*l, HI_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
              data_lim=data_lim, color='m', alpha=0.1, disk_scales=disk_scales, label='I Yoshino maxdisc')
    

ax.set_ylim(0., 2.5)
ax.set_xlim(0., 130.)
ax.axhline(y=1., ls='-', color='grey')
plot_SF(ax)
ax.grid()

plt.savefig('..\\..\pics\\He\\'+name+'.png', format='png', bbox_inches='tight');


Влияние изменения M/L:


In [113]:
%%time

plot_param_depend(ax=plt.gca(), data_lim=data_lim, color='g', alpha=0.3, disk_scales=disk_scales, label='I maxdisc', N = 10,
                  total_gas_data=zip(r_HI_dens, [He_coeff*(y_interp_(l[0]) + l[1]) for l in zip(r_HI_dens, HI_dens)])[1:14], 
                  epicycl=epicyclicFreq_real, 
                  gas_approx=spl_gas, 
                  sound_vel=sound_vel, 
                  scale=scale, 
                  sigma_max=sig_R_maj_max, 
                  sigma_min=sig_R_maj_min, 
                  star_density_max=map(lambda c: lambda l: surf_density(mu_disc(l, mu0=mu0d_I, h=h_disc_I), c, 'I'), np.linspace(1., 12., 10)), 
                  star_density_min=map(lambda c: lambda l: surf_density(mu_disc(l, mu0=mu0d_I, h=h_disc_I), c, 'I'), np.linspace(1., 12., 10)));


Wall time: 6min 28s

Замена spl_gas на gas_approx:


In [117]:
%%time

plot_param_depend(ax=plt.gca(), data_lim=data_lim, color='g', alpha=0.3, disk_scales=disk_scales, label='I maxdisc', N = 2,
                  total_gas_data=zip(r_HI_dens, [He_coeff*(y_interp_(l[0]) + l[1]) for l in zip(r_HI_dens, HI_dens)])[1:14], 
                  epicycl=epicyclicFreq_real, 
                  gas_approx=[spl_gas, gas_approx], 
                  sound_vel=sound_vel, 
                  scale=scale, 
                  sigma_max=sig_R_maj_max, 
                  sigma_min=sig_R_maj_min, 
                  star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
                  star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'));


Wall time: 31.6 s

Разные реалистичные дисперсии:


In [116]:
%%time

plot_param_depend(ax=plt.gca(), data_lim=data_lim, color='g', alpha=0.3, disk_scales=disk_scales, label='I maxdisc', N = 10,
                  total_gas_data=zip(r_HI_dens, [He_coeff*(y_interp_(l[0]) + l[1]) for l in zip(r_HI_dens, HI_dens)])[1:14], 
                  epicycl=epicyclicFreq_real, 
                  gas_approx=spl_gas, 
                  sound_vel=[[c*np.exp(-2*l/r25) if l < r25 else c*np.exp(-2.) for l in r_g_dens[1:]] for c in list(np.linspace(6., 100., 10))], 
                  scale=scale, 
                  sigma_max=sig_R_maj_max, 
                  sigma_min=sig_R_maj_min, 
                  star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
                  star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'));


Wall time: 2min 37s

Влияние наклона на результат

Необходимо узнать, как влияет разброс у гле наклона на итоговый результат. К сожалению кроме как вручную это сложно сделать.


In [109]:
# fig = plt.figure(figsize=[10,8])

# gas_approxes = []
# spl_gases = []

# for i in [36., 40.]:
#     incl = i
#     sin_i, cos_i = np.sin(incl*np.pi/180.), np.cos(incl*np.pi/180.)

#     # Данные по кинематике газа Struve, WSRT (не исправлено за наклон)
#     r_wsrt, vel_wsrt, e_vel_wsrt = zip(*np.loadtxt("v_gas_WSRT.dat", float))
#     r_wsrt, vel_wsrt, e_vel_wsrt = correct_rotation_curve(r_wsrt, vel_wsrt, e_vel_wsrt,  0.0, v0, incl)

#     # Данные по кинематике газа Noordermee 2007, WSRT (не исправлено за наклон?)
#     r_noord, vel_noord, e_vel_noord = zip(*np.loadtxt("v_gas_noord.dat", float))
#     r_noord, vel_noord, e_vel_noord = correct_rotation_curve(r_noord, vel_noord, e_vel_noord,  0.0, v0, incl)
    
#     plt.plot(r_wsrt, vel_wsrt, '.-', label="gas Struve")
#     plt.plot(r_noord, vel_noord, '.-', label="gas Noordermeer 2007")

#     gas_approx = poly1d(polyfit(r_ma_n, vel_ma_n, deg=5))
#     test_points = np.linspace(min(r_ma_n), max(r_ma_n), 100)
#     plt.plot(test_points, gas_approx(test_points), '--', label='approx')
#     gas_approxes.append(gas_approx)

#     spl_gas = inter.UnivariateSpline(r_noord, vel_noord, k=3, s=10000.)
#     plt.plot(test_points, spl_gas(test_points), '-', label='spl')
#     spl_gases.append(spl_gas)


# plt.ylim(0, 450)
# plt.legend(loc='lower right');

In [110]:
# fig = plt.figure(figsize=[12, 8])
# for ind, i in enumerate([36., 40.]):
#     incl = i
#     sin_i, cos_i = np.sin(incl*np.pi/180.), np.cos(incl*np.pi/180.)
#     plt.plot(test_points, [epicyclicFreq_real(gas_approxes[ind], x, scale) for x in test_points], '-', label='poly')
#     plt.plot(test_points, [epicyclicFreq_real(spl_gases[ind], x, scale) for x in test_points], '-', label='spline')
#     print epicyclicFreq_real(spl_gases[ind], 10., scale)

# def epicyclicFreq_real_(spl_gas, x, scale):
#     '''продливаем дальше без производной на плато'''
#     if x < 60.:
#         return epicyclicFreq_real(spl_gas, x, scale)
#     else:
#         return sqrt(2)*arctanlaw(x, m,c,d)/(x*scale)
# #     TODO: check scale multiplication
    
# # plt.plot(np.linspace(1., 100., 100), [epicyclicFreq_real_(gas_approx, x, scale) for x in np.linspace(1., 100., 100)], '-', label='contin')

# plt.xlabel('$R, arcsec$')
# plt.ylabel('$\kappa,\, km/s/kpc$', fontsize=15)
# plt.ylim(0, 100)
# plt.legend();

In [434]:
plt.errorbar(r_sig_ma, sig_ma, yerr=e_sig_ma, fmt='.', marker='.', mew=0, color='red', label='$\sigma_{los}^{maj}$')
for ind, i in enumerate([60., 70.]):
    incl = i
    sin_i, cos_i = np.sin(incl*np.pi/180.), np.cos(incl*np.pi/180.)
#     plt.plot(points, map(sig_R_maj_minmin, points), label = 'minmin')
    plt.plot(points, map(sig_R_maj_min, points), label = 'min')
    plt.plot(points, map(sig_R_maj_max, points), label = 'max')
#     plt.plot(points, map(sig_R_maj_maxmax, points), label = 'maxmax')
#     plt.plot(points, map(sig_R_maj_maxmaxtrue, points), label = 'maxmaxtrue')

plt.legend()
plt.ylim(0,400)
plt.xlim(0,100);



In [435]:
# plot_2f_vs_1f(ax=axes[4], total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[:15], epicycl=epicyclicFreq_real, 
#               gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
#               sigma_max=sig_R_maj_max, 
#               sigma_min=sig_R_maj_min, 
#               star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
#               star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I'), 
#               data_lim=data_lim, color='g', alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc')
    
#     plot_2f_vs_1f(ax=axes[4], total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[:15], epicycl=epicyclicFreq_real, 
#               gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
#               sigma_max=sig_R_maj_max, 
#               sigma_min=sig_R_maj_min, 
#               star_density_max=lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=0.38), 
#               star_density_min=lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=0.38), 
#               data_lim=data_lim, color='m', alpha=0.2, disk_scales=disk_scales, label='SPITZER 3.6 maxdisc')

In [436]:
max_coeffs_incl = []

for ind, i in enumerate([60., 70.]):
    incl = i
    sin_i, cos_i = np.sin(incl*np.pi/180.), np.cos(incl*np.pi/180.)

    max_coeffs = {}

    for photom in all_photometry:
        disc_max = 2.2*photom[5]
        max_coeff = 0.85*spl_gas(disc_max)/disc_vel(disc_max, photom[7](0), photom[5], scale)
        submax_coeff = 0.6*spl_gas(disc_max)/disc_vel(disc_max, photom[7](0), photom[5], scale)

        print '{:15s}: M/L was {:2.2f} and for max it equal {:2.2f}, for submax equal {:2.2f}'.format(photom[0], photom[6], photom[6]*max_coeff**2, photom[6]*submax_coeff**2)
        max_coeffs[photom[0]] = [photom[6]*max_coeff**2, photom[6]*submax_coeff**2]
        
    max_coeffs_incl.append(max_coeffs)


YOSHINO I      : M/L was 0.97 and for max it equal 1.19, for submax equal 0.59
YOSHINO V      : M/L was 1.74 and for max it equal 1.76, for submax equal 0.88
YOSHINO J      : M/L was 0.95 and for max it equal 0.46, for submax equal 0.23
SPITZER 3.6    : M/L was 0.65 and for max it equal 0.44, for submax equal 0.22
SPITZER 3.6 faceon: M/L was 0.65 and for max it equal 0.88, for submax equal 0.44
GALFIT K       : M/L was 0.79 and for max it equal 0.61, for submax equal 0.30
S4G 3.6        : M/L was 0.65 and for max it equal 0.99, for submax equal 0.49
YOSHINO I      : M/L was 0.97 and for max it equal 1.19, for submax equal 0.59
YOSHINO V      : M/L was 1.74 and for max it equal 1.76, for submax equal 0.88
YOSHINO J      : M/L was 0.95 and for max it equal 0.46, for submax equal 0.23
SPITZER 3.6    : M/L was 0.65 and for max it equal 0.44, for submax equal 0.22
SPITZER 3.6 faceon: M/L was 0.65 and for max it equal 1.29, for submax equal 0.64
GALFIT K       : M/L was 0.79 and for max it equal 0.61, for submax equal 0.30
S4G 3.6        : M/L was 0.65 and for max it equal 0.99, for submax equal 0.49

In [437]:
fig = plt.figure(figsize=[10, 6])
ax = plt.gca()

for ind, i in enumerate([60., 70.]):
    incl = i
    sin_i, cos_i = np.sin(incl*np.pi/180.), np.cos(incl*np.pi/180.)
    
    plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=max_coeffs_incl[ind]['YOSHINO I'][0], band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=max_coeffs_incl[ind]['YOSHINO I'][0], band='I'), 
              data_lim=data_lim, color=cm.rainbow(np.linspace(0, 1, 4))[ind], alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc inc={}'.format(incl))
    
#     plot_2f_vs_1f(ax=ax, total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[:15], epicycl=epicyclicFreq_real, 
#           gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
#           sigma_max=sig_R_maj_max, 
#           sigma_min=sig_R_maj_min, 
#           star_density_max=lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=max_coeffs_incl[ind]['SPITZER 3.6'][0]), 
#           star_density_min=lambda l: s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=max_coeffs_incl[ind]['SPITZER 3.6'][0]), 
#           data_lim=data_lim, color=cm.rainbow(np.linspace(0, 1, 4))[ind+2], alpha=0.2, disk_scales=disk_scales, label='SPITZER 3.6 maxdisc inc={}'.format(incl))

plt.ylim(0., 2.5)
plt.xlim(0, 130)
plt.axhline(y=1., ls='-', color='grey')
plot_SF(ax)
plt.grid()
plt.savefig('..\\..\pics\\incl_summary\\'+name+'.png', format='png', bbox_inches='tight');



In [438]:
incl = 65.
sin_i, cos_i = np.sin(incl*np.pi/180.), np.cos(incl*np.pi/180.)

Картинки для статьи


In [102]:
import matplotlib as mpl
mpl.style.use('classic')

In [103]:
fig = plt.figure(figsize=[16, 12])

test_points = np.linspace(0., 250., 100.)

ax = plt.subplot2grid((2,2), (0, 0))
# ax.imshow(ImagePIL.open('n4258_SDSS_labeled.jpg'), aspect='auto')
ax.imshow(ImagePIL.open('sdss4258.png'), aspect='auto')
ax.set_xticks([])
ax.set_yticks([])

ax = plt.subplot2grid((2,2), (1, 0))
ax.errorbar(r_sig_ma, sig_ma, yerr=e_sig_ma, fmt='.', marker='.', mew=0, color='red', label='$\sigma_{los}^{maj}$', ms=15)
ax.plot(points, map(sig_R_maj_min, points), label=r'$\sigma_R^{min}$')
ax.plot(points, map(sig_R_maj_max, points), '--', label=r'$\sigma_R^{max}$')
ax.legend(fontsize=30)


for tick in ax.yaxis.get_major_ticks():
    tick.label.set_fontsize(23)
for tick in ax.xaxis.get_major_ticks():
    tick.label.set_fontsize(23)

ax.set_ylim(0,220)
ax.set_xlim(0, 100)  
ax.set_ylabel(r'$\sigma, km/s$', fontsize=30)
ax.set_xlabel(r'$R,\,arcsec$', fontsize=30)
ax.grid()

ax = plt.subplot2grid((2,2), (1, 1))

# ax.plot(r_HI_dens, HI_dens, 'd-', label=r'$\rm{HI}$', ms=10)
# ax.plot(r_mol_dens, mol_dens, 's-', label=r'$\rm{H_2}$', ms=10)
# ax.plot(r_g_dens, gas_dens, 'o-', label=r'$\rm{HI+H_2}$', ms=10)

plt.errorbar(r_g_dens, gas_dens1[24::3], hi_yerr, fmt='d-', capsize=5, label=r'$\rm{HI}$', ms=8)
plt.errorbar(r_g_dens[:8], gas_dens1[0:24:3], h2_yerr, fmt='s-', label=r'$\rm{H_2}$', ms=8, capsize=5)
plt.errorbar(r_g_dens[:8], (np.array(gas_dens1[0:24:3])+np.array(gas_dens1[24:48:3]))*He_coeff, (hi_yerr[:, :8]+h2_yerr)*He_coeff, fmt='o-', label=r'$\rm{HI+H_2}$', ms=8, capsize=5)
tmp = (np.array(gas_dens1[0:24:3])+np.array(gas_dens1[24:48:3]))*He_coeff
tmp_err = (hi_yerr[:, :8]+h2_yerr)*He_coeff
plt.errorbar(r_g_dens[7:], np.concatenate([[tmp[-1]], np.array(gas_dens1[48::3])*He_coeff]), 
             np.concatenate([np.array([tmp_err[:, -1]]), (hi_yerr[:, 8:].T)*He_coeff]).T, fmt='o-', color='r', ms=8, capsize=5)

plt.semilogy(test_points, [surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I') for l in test_points], '--', lw=3, color='g')
plt.semilogy(test_points, [s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=0.38) for l in test_points], '-.', lw=3, color='m')

# ax.plot(r_g_dens, gas_dens, 'd-', label=r'$\rm{HI}$', ms=10)
# ax.plot(r_g_dens, [y_interp_(l, h_disc_R) for l in r_g_dens], '--', label=r'$\rm{H_2}$')
# ax.plot(r_g_dens, [He_coeff*(y_interp_(l[0], h_disc_R) + l[1]) for l in zip(r_g_dens, gas_dens)], 'o-', label=r'$\rm{HI+H_2}$', ms=10)
ax.grid()
ax.set_xlim(0, 200)
ax.set_ylim(1.0, 1550)
ax.legend(fontsize=20)

ax.set_ylabel(u'$\Sigma,\,M_\u2609/\mathrm{pc}^2$', fontsize=30, labelpad=-5)
ax.set_xlabel(r'$R,\,arcsec$', fontsize=30)

for tick in ax.yaxis.get_major_ticks():
    tick.label.set_fontsize(23)
for tick in ax.xaxis.get_major_ticks():
    tick.label.set_fontsize(23)
    
ax.yaxis.set_tick_params(length=10, which='major')
ax.yaxis.set_tick_params(length=7, which='minor')

ax = plt.subplot2grid((2,2), (0, 1))
# ax.errorbar(r_wsrt, vel_wsrt, yerr=e_vel_wsrt, fmt='.', marker='.', mew=1, label = 'data', ms=15, color='red')

ax.errorbar(r_co, vel_co, yerr=[0.]*len(r_co), fmt='.', marker='s', mew=0., label = r'Sawada-Satoh et al. (2007) $CO$', ms=4, color='red')
ax.errorbar(r_hi, vel_hi, yerr=[1.]*len(vel_hi), fmt='.', marker='.', mew=1, label = r'van Eymeren et al. (2011) $\rm{HI}$', ms=15, color='red')

# plt.plot(r_wsrt, vel_wsrt, '.', label="gas Struve")
# plt.plot(r_noord, vel_noord, '^', label=r"Noordermeer et al. (2007)")
# plt.plot(r_co, vel_co, '.', label=r'Sawada-Satoh et al. (2007) $CO$', color='r')
# plt.plot(r_hi, vel_hi, 'd', label=r'van Eymeren et al. (2011) $\rm{HI}$')
# plt.plot(r_ma_n, vel_ma_n, 's', label='HI from fig')

ax.plot(test_points, spl_gas(test_points), '-', lw=3, color='b')


# ax.plot(test_points, 0.85*spl_gas(test_points), '--', label='max disc limit')

# ax.plot(r, vel, '.', label = 'Noord thesis')

max_coeffs = {}
for ind, photom in enumerate(all_photometry):
    if photom[0] in ['YOSHINO I', 'SPITZER 3.6']:
        disc_max = 2.2*photom[5]
        max_coeff = 0.85*spl_gas(disc_max)/disc_vel(disc_max, photom[7](0), photom[5], scale)
        submax_coeff = 0.6*spl_gas(disc_max)/disc_vel(disc_max, photom[7](0), photom[5], scale)

        if type(photom[5]) == tuple:
            ax.plot(test_points, map(lambda l: disc_vel(l, max_coeff**2 *photom[7][0](0), photom[5][0], scale, 
                                                         Sigma0_2=max_coeff**2 *photom[7][1](0), h_2=photom[5][1]), test_points), '--', label=r'Gutierrez (2011) $R$', lw=3)
        else:
            if photom[0] == 'YOSHINO I':
                ax.plot(test_points, map(lambda l: disc_vel(l, max_coeff**2 * photom[7](0), photom[5], scale), test_points), '--', label=r'Yoshino & Ichikawa (2008) $I$ max', lw=3, color='g')
            else:
                ax.plot(test_points, map(lambda l: disc_vel(l, max_coeff**2 * photom[7](0), photom[5], scale), test_points), '-.', 
                        label=r'$S^4G$ Salo et al. (2015) $3.6$ max', lw=3, color='m')
        

ax.grid(linewidth=0.5)
ax.set_ylim(0, 300)
ax.set_xlim(0, 200)
ax.legend(fontsize=18, loc='lower right')
ax.set_ylabel(r'$v,\,km/s$', fontsize=30, labelpad=-5)
# ax.set_xlabel(r'$R,\,arcsec$', fontsize=20)

# for tick in ax.yaxis.get_major_ticks():
#     tick.label.set_fontsize(12)
# for tick in ax.xaxis.get_major_ticks():
#     tick.label.set_fontsize(12)
ax.set_xticklabels([])
for tick in ax.yaxis.get_major_ticks():
    tick.label.set_fontsize(23)
for tick in ax.xaxis.get_major_ticks():
    tick.label.set_fontsize(23)

# plt.tight_layout(pad=0.1, w_pad=0.1, h_pad=0.1)
fig.subplots_adjust(wspace=0.2, hspace=0.02)
plt.savefig(paper_imgs_dir+'4258_obs_data.eps', format='eps', bbox_inches='tight')
plt.savefig(paper_imgs_dir+'4258_obs_data.png', format='png', bbox_inches='tight')
plt.savefig(paper_imgs_dir+'4258_obs_data.pdf', format='pdf', dpi=150, bbox_inches='tight')
plt.show()


C:\Anaconda\lib\site-packages\ipykernel\__main__.py:3: DeprecationWarning: object of type <type 'float'> cannot be safely interpreted as an integer.
  app.launch_new_instance()

Вид со спиралями:


In [108]:
fig = plt.figure(figsize=[12, 5])

# plt.plot(r_HI_dens[1:-17], [1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
#                     zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], HI_dens)][1:-17], 'd-', label=r'$\rm{HI}$', color='b', ms=10)
# plt.plot(r_mol_dens[1:], [1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
#                     zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], mol_dens)][1:], 'o-', label=r'$\rm{H_2}$')
plt.plot(r_g_dens[1:-17], [Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
                    zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], gas_dens)][1:-17], 'o-', label=r'$\rm{HI}+\rm{H_2}$', color='b', ms=10)
# plt.plot(r_g_dens[1:-17], [1./Qg(epicycl=l[0], sound_vel=11., gas_density=l[1]) for l in 
#                     zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], gas_dens)][1:-17], 'o-', label=r'$total\: &\: c=11$')


# plt.fill_between(r_g_dens[1:-17], y1=[0. for _ in r_g_dens[1:-17]], y2=[1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in 
#                     zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], gas_dens)][1:-17], color='r', alpha=0.15)
# plt.fill_between(r_HI_dens[1:-17], y1=[1./Qg(epicycl=l[0], sound_vel=sound_vel, gas_density=l[1]) for l in zip([epicyclicFreq_real(spl_gas, x, scale) for x in r_g_dens], HI_dens)][1:-17], 
#                  y2=[0.]*len(r_HI_dens[1:-17]), color='b', alpha=0.15)

# plt.axhline(y=1, ls='--')
plt.legend(fontsize=30, loc='upper right')
plot_SF(plt.gca())
# plt.ylabel('$Q^{-1}$', fontsize=15)
# plt.title(name)
for q_ in [1., 1.5, 2., 3.]:
    plt.axhline(y=q_, lw=10, alpha=0.15, color='grey')
plt.grid()
# plt.ylim(0, 1.2)
# plt.savefig('..\\..\pics\\instab_spirals\\'+name+'_spiral'+'.png', format='png', bbox_inches='tight')
ax = plt.gca()
ax.set_xlabel(r'$R, arcsec$', fontsize=36)
ax.set_ylabel(r'$Q_{g}$', fontsize=36)
ax.text(40, 3.8, r'$\rm{NGC\:4258}}$', fontsize=45)
ax.set_xlim(0, 610.)
ax.set_yticks([0., 1., 2., 3., 4.])
for tick in ax.yaxis.get_major_ticks():
    tick.label.set_fontsize(24)
for tick in ax.xaxis.get_major_ticks():
    tick.label.set_fontsize(24)
plt.savefig(paper_imgs_dir+'4258_spiral.eps', format='eps', bbox_inches='tight')
plt.savefig(paper_imgs_dir+'4258_spiral.png', format='png', bbox_inches='tight')
plt.savefig(paper_imgs_dir+'4258_spiral.pdf', format='pdf', dpi=150, bbox_inches='tight')
plt.show()


Эксперименты

Ошибки из-за газа и остального:


In [108]:
(r_g_dens[:8], (np.array(gas_dens1[0:24:3])+np.array(gas_dens1[24:48:3]))*He_coeff, (hi_yerr[:, :8]+h2_yerr)*He_coeff)


Out[108]:
([10.948226461517876,
  31.749856738401821,
  50.361841722982234,
  70.068649353714406,
  89.775456984446549,
  109.48226461517876,
  129.18907224591095,
  148.89587987664314],
 array([ 172.897149  ,   94.6397736 ,   36.43304963,   17.94329105,
          15.31355151,   10.96041584,   11.57003284,   10.56364656]),
 array([[ 104.57499756,   46.40281272,   15.68188272,    9.26967827,
           10.78513624,    4.0648359 ,    3.65164402,    2.46805451],
        [ 116.89636405,   37.04404476,   14.31798921,    8.63941818,
           12.77624648,    3.90579227,    3.62578992,    2.3616809 ]]))

In [110]:
gdd = zip(r_g_dens[:8], [172.897149  ,   94.6397736 ,   36.43304963,   17.94329105,
          15.31355151,   10.96041584,   11.57003284,   10.56364656],
   [104.57499756,   46.40281272,   15.68188272,    9.26967827,
           10.78513624,    4.0648359 ,    3.65164402,    2.46805451], [116.89636405,   37.04404476,   14.31798921,    8.63941818,
           12.77624648,    3.90579227,    3.62578992,    2.3616809])[:-1]
gdd


Out[110]:
[(10.948226461517876, 172.897149, 104.57499756, 116.89636405),
 (31.749856738401821, 94.6397736, 46.40281272, 37.04404476),
 (50.361841722982234, 36.43304963, 15.68188272, 14.31798921),
 (70.068649353714406, 17.94329105, 9.26967827, 8.63941818),
 (89.775456984446549, 15.31355151, 10.78513624, 12.77624648),
 (109.48226461517876, 10.96041584, 4.0648359, 3.90579227),
 (129.18907224591095, 11.57003284, 3.65164402, 3.62578992)]

In [111]:
sigma_max_range = [sig_R_maj_max, lambda l: sig_R_maj_max(l)+20., lambda l: sig_R_maj_max(l)-20. ]
sigma_min_range = [sig_R_maj_min, lambda l: sig_R_maj_min(l)+20., lambda l: sig_R_maj_min(l)-20. ]

In [113]:
sound_vel_range = [6., 11.]

In [114]:
total_gas_data_range = [[(l[0], l[1]) for l in gdd], [(l[0], l[1]-l[2]) for l in gdd], [(l[0], l[1]+l[3]) for l in gdd]]

In [120]:
import itertools

cartesian = []
for element in itertools.product(sigma_max_range, sigma_min_range, sound_vel_range, total_gas_data_range):
#     print(element)
    cartesian.append(element)

In [121]:
len(cartesian), 3*3*3*2


Out[121]:
(54, 54)

In [122]:
cartesian[0]


Out[122]:
(<function utils.wrapper>,
 <function utils.wrapper>,
 6.0,
 [(10.948226461517876, 172.897149),
  (31.749856738401821, 94.6397736),
  (50.361841722982234, 36.43304963),
  (70.068649353714406, 17.94329105),
  (89.775456984446549, 15.31355151),
  (109.48226461517876, 10.96041584),
  (129.18907224591095, 11.57003284)])

In [129]:
%%time

fig = plt.figure(figsize=[16, 7])

plot_2f_vs_1f(ax=plt.gca(), total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              data_lim=data_lim, color='m', alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc',
              ML = 1.00,
              CO = lambda l: y_interp_(l))

plot_param_depend(ax=plt.gca(), 
                  data_lim=data_lim,
                  color='g', 
                  alpha=0.3, 
                  disk_scales=disk_scales, 
                  label='I maxdisc', 
                  N = 54,
                  total_gas_data=[l[3] for l in cartesian], 
                  epicycl=epicyclicFreq_real, 
                  gas_approx=spl_gas, 
                  sound_vel=[l[2] for l in cartesian], 
                  scale=scale, 
                  sigma_max=[l[0] for l in cartesian], 
                  sigma_min=[l[1] for l in cartesian], 
                  star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
                  star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'))


Wall time: 10min 10s

И макс ошибки:


In [128]:
%%time

fig = plt.figure(figsize=[16, 7])

plot_2f_vs_1f(ax=plt.gca(), total_gas_data=zip(r_g_dens, map(lambda l: l, gas_dens))[1:15], epicycl=epicyclicFreq_real, 
              gas_approx=spl_gas, sound_vel=sound_vel, scale=scale, 
              sigma_max=sig_R_maj_max, 
              sigma_min=sig_R_maj_min, 
              star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.00, band='I'), 
              data_lim=data_lim, color='m', alpha=0.2, disk_scales=disk_scales, label='I Yoshino maxdisc',
              ML = 1.00,
              CO = lambda l: y_interp_(l))

plot_param_depend(ax=plt.gca(), 
                  data_lim=data_lim,
                  color='g', 
                  alpha=0.3, 
                  disk_scales=disk_scales, 
                  label='I maxdisc', 
                  N = 54,
                  total_gas_data=[l[3] for l in cartesian], 
                  epicycl=epicyclicFreq_real, 
                  gas_approx=spl_gas, 
                  sound_vel=[l[2] for l in cartesian], 
                  scale=scale, 
                  sigma_max=[l[0] for l in cartesian], 
                  sigma_min=[l[1] for l in cartesian], 
                  star_density_max=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'), 
                  star_density_min=lambda l: surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=1.0, band='I'),
                  max_range=True)


Wall time: 10min 4s

Plotly:


In [118]:
from plotly import tools
from plotly.offline import init_notebook_mode, iplot
import plotly.plotly as py
import plotly.graph_objs as go
init_notebook_mode(connected=True)

acc_dot = go.Scatter(
    x = r_g_dens[:7], 
    y = invQeff,
    mode='lines+markers',
    name = 'Qeff',
    marker=dict(
        size='16',
        color = ['#770000']*len(invQeff))
)
qgdat = go.Scatter(
    x = r_g_dens[:5], 
    y = invQg,
    mode='lines+markers',
    name = 'Qg',
    marker=dict(
        size='16',
        color = ['#007700']*len(invQeff))
)
data = [acc_dot, qgdat]

iplot(data, filename='scatter-plot-with-colorscale')


Предсказание минимального Q для неустойчивости:


In [127]:
qg = 6.16
qs = 11.06
s = 0.03587

def predict_hydro_unstable_Qs(Qg, s):
    '''Рассчитывает величину Qs, при которой достигается минимальная неустойчивость.
    Для этого выражения для двухжидкостной неуст в кинематич. приближении приравнивается 1 
    и максимум выражения ниже и есть искомое.'''
    fuu = lambda l: 2*k*Qg*(1+k**2*s**2)/(1+k**2)/(Qg+Qg*k**2*s**2 - 2*s*k)
    candidate_Qs = max([fuu(k) for k in np.arange(0.01, 60000., 1.)])
    Qeff = findInvKinemQeffBrute(candidate_Qs, Qg, s, np.arange(0.01, 60000., 1.))[0]
    assert abs(Qeff-1) < 0.2
    return candidate_Qs

In [120]:
predict_hydro_unstable_Qs(qg, s)


Out[120]:
1.0118366914349535

Проверка:


In [128]:
Qgs = []
Qss = []
invQeff = []
for r, gd in zip(r_g_dens, gas_dens)[2:7]: #только до 90" берем, дальне нет данных по дисперсии
    Qgs.append(Qg(epicycl=epicyclicFreq_real(gas_approx, r, scale), sound_vel=sound_vel, gas_density=gd*He_coeff))
    Qss.append(predict_hydro_unstable_Qs(Qgs[-1], sound_vel/sig_R_maj_max(r)))
    qeff = findInvHydroQeffBrentq(Qss[-1], Qgs[-1], sound_vel/sig_R_maj_max(r), np.arange(0.01, 60000., 1.))
    print 'Qs = {:2.2f}; Qg = {:2.2f}; Qeff = {:2.2f}'.format(Qss[-1], Qgs[-1], 1./qeff[1])
    invQeff.append(qeff)


Qs = 1.08; Qg = 1.27; Qeff = 1.00
Qs = 1.06; Qg = 1.70; Qeff = 1.00
Qs = 1.06; Qg = 1.69; Qeff = 1.00
Qs = 1.05; Qg = 2.25; Qeff = 1.00
Qs = 1.05; Qg = 1.99; Qeff = 1.00

In [130]:
plt.plot(r_g_dens[2:7], map(lambda l: 1./l, Qgs), '.-', label='Qg')
plt.plot(r_g_dens[2:7], zip(*invQeff)[1], 'v-', label='Qeff')
plt.ylim(0., 1.)
plt.xlim(0., 8./0.072)
plt.legend();


WKB приближение

Проверим применимость WKB приближения, т.е. $k\times r \gg 1$:


In [ ]:

Для $I$:


In [109]:
plot_WKB_dependencies(r_g_dens=r_g_dens[:15], 
                    gas_dens=map(lambda l: l, gas_dens)[:15], 
                    epicycl=lambda l: epicyclicFreq_real(spl_gas, l, scale), 
                    sound_vel=sound_vel,
                    star_density=[surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I') for l in r_g_dens[:15]], 
                    sigma=sig_R_maj_max, 
                    scale=scale,
                    krange=arange(0.01, 1000, 0.01))
plt.xlabel(r'$k\times r$', fontsize=20)
plt.title('WKB check')
plt.axvline(x=1, alpha=0.1)
plt.xlim(0, 100);


Исходная зависимость:


In [110]:
plot_k_dependencies(r_g_dens=r_g_dens[:15], 
                    gas_dens=map(lambda l: l, gas_dens)[:15], 
                    epicycl=lambda l: epicyclicFreq_real(spl_gas, l, scale), 
                    sound_vel=sound_vel,
                    star_density=[surf_density(mu=mu_disc(l, mu0=mu0d_I, h=h_disc_I), M_to_L=0.82, band='I') for l in r_g_dens[:15]], 
                    sigma=sig_R_maj_max,
                    krange=arange(0.01, 1000, 0.01))
plt.xlabel(r'$\bar{r}$', fontsize=20)
plt.axvline(x=1, alpha=0.1)
plt.xlim(0, 100);


Для $S^4G$:


In [111]:
plot_WKB_dependencies(r_g_dens=r_g_dens[:15], 
                    gas_dens=map(lambda l: l, gas_dens)[:15], 
                    epicycl=lambda l: epicyclicFreq_real(spl_gas, l, scale), 
                    sound_vel=sound_vel,
                    star_density=[s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=0.38) for l in r_g_dens[:15]], 
                    sigma=sig_R_maj_max, 
                    scale=scale,
                    krange=arange(0.01, 1000, 0.01))
plt.xlabel(r'$k\times r$', fontsize=20)
plt.title('WKB check')
plt.axvline(x=1, alpha=0.1)
plt.xlim(0, 100);



In [112]:
plot_k_dependencies(r_g_dens=r_g_dens[:15], 
                    gas_dens=map(lambda l: l, gas_dens)[:15], 
                    epicycl=lambda l: epicyclicFreq_real(spl_gas, l, scale), 
                    sound_vel=sound_vel,
                    star_density=[s4g_surf_density(mu_disc(l, mu0=mu0d_36, h=h_disc_36), M_to_L=0.38) for l in r_g_dens[:15]], 
                    sigma=sig_R_maj_max,
                    krange=arange(0.01, 1000, 0.01))
plt.xlabel(r'$\bar{r}$', fontsize=20)
plt.axvline(x=1, alpha=0.1)
plt.xlim(0, 100);