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]: