从HaloSat南天拟合到M31方向域外外推 — From HaloSat southern-sky fit to the M31 out-of-domain extrapolation

面向物理系本科一年级 · 可执行教程

Author

M31 CGM Team

Published

July 18, 2026

从HaloSat南天拟合到M31方向域外外推

教程目标:理解 Kaaret et al. (2020) HaloSat 的 empirical disk + adiabatic halo 模型如何从73个南天高银纬场拟合,再域外外推到M31方向,变成Figure 3上的一个 supplemental extrapolation 点。 Tutorial goal: Understand how Kaaret et al. (2020) HaloSat’s empirical disk plus adiabatic halo model, fitted to 73 southern high-latitude fields, is extrapolated outside its fit domain toward M31 to become a supplemental extrapolation point on Figure 3.

目标读者:物理系本科一年级,已学完普通物理(电磁学/光学),了解基本的原子物理概念(能级、跃迁),但不需要天文观测经验。 Target audience: First-year physics undergraduates who have completed general physics (electromagnetism/optics) and basic atomic physics, without requiring astronomical observing experience.

核心问题:HaloSat 是一颗 CubeSat,它用73个 b<-30° 的南天场拟合出银河系热气体的三维形态模型。M31 在 b≈-21.6°,全部十四场都在拟合域外。这个模型如何”外推”到M31方向?为什么它只是一个 supplemental extrapolation,而不是直接预测?


0. 准备工作:环境与数据

本教程只需要 Python 标准科学栈。所有数据文件已随教程提供。

Code
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pathlib import Path

plt.style.use('seaborn-v0_8-whitegrid')
plt.rcParams['font.size'] = 12
plt.rcParams['figure.dpi'] = 150
plt.rcParams['savefig.dpi'] = 300
# NOTE: do NOT add a CJK font fallback here — see SKILL.md
# All matplotlib text labels stay English-only.

DATA = Path("assets/data")
print("Environment ready!")
Environment ready!

1. 背景知识:HaloSat 是什么?

1.1 HaloSat:一颗看X射线的 CubeSat

HaloSat 是一颗专门观测软X射线(约0.2–2 keV)的 CubeSat——一种体积很小、成本较低的卫星。它不是成像望远镜,而是用 silicon-drift detectors(硅漂移探测器)和宽视场来测量大天区的X射线背景。它的科学目标是理解银河系周围的热气体——circumgalactic medium, CGM——是什么形状的。

1.2 银河系热气体的两种”形状”

银河系周围 \(10^6\)\(10^7\) K 的热气体发出软X射线。但它的空间分布是盘状(disk-dominated)还是球状(spherical halo)?这关系到银河系如何吸积和释放气体。Kaaret et al. (2020) 用 HaloSat 的73个南天高银纬场(\(b<-30^\circ\))的 emission measure(发射量度,EM)数据来回答这个问题。

Emission measure 的定义是沿视线积分 \(\int n_e n_H \, ds\)(单位 cm\(^{-6}\) pc),它正比于X射线发射强度。EM 越大,说明该方向上的热气体越多或路径越长。

1.3 论文结论:disk-dominated 且 patchy

Kaaret et al. (2020) 比较了 disk 和 halo 两种形态模型后,结论是:soft X-ray emitting CGM 在该南天样本中是 disk-dominated 的,而且有 patchiness(不均匀性)。最终采用的 composite model(empirical disk + adiabatic halo)的拟合优度是 \(\chi^2 \approx 71.7/70\)


2. HaloSat 的三维模型:empirical disk + adiabatic halo

2.1 Empirical disk(经验盘)

盘成分的密度模型是:

\[n_{\mathrm{disk}}(R, z) = n_0 \cdot \Sigma(R) \cdot \exp\left(-\frac{|z|}{z_0}\right)\]

其中: - \(n_0 = 0.0081\) cm\(^{-3}\) 是盘的密度归一化; - \(z_0 = 1.60\) kpc 是垂直标高; - \(\Sigma(R)\) 是一个 piecewise(分段)的径向函数,描述盘密度随银心距 \(R\) 的变化。

2.2 Adiabatic halo(绝热晕)

晕成分采用 Fang et al. (2013) 的 polytropic(多方)模型,描述在 NFW 势阱中处于流体静力学平衡的气体:

  • \(\rho_V = 4.8 \times 10^{-5}\) cm\(^{-3}\)(virial 密度归一化);
  • \(R_s = 21.7\) kpc(NFW scale radius);
  • \(C_V = 12\)(concentration 参数)。

这是一个”绝热”气体晕——温度随密度按绝热关系变化,而不是等温的。

2.3 关键:发射量度的计算方式

模型预测的 EM 通过沿视线积分 \((n_{\mathrm{disk}} + n_{\mathrm{halo}})^2\) 得到:

\[\mathrm{EM}_{\mathrm{model}} = \int (n_d + n_h)^2 \, ds\]

注意这里保留了 disk-halo cross term(交叉项) \(2 n_d n_h\)。这个 convention 是通过对73场 catalog 的 \(\chi^2\) closure 验证确定的——只有保留交叉项,才能复现论文的拟合统计量 \(\chi^2 = 71.665\)

关键假设:论文没有说明拟合得到的 \(n\)\(n_e\)\(n_H\)、total-ion 还是 total-particle 密度。因此本项目不额外乘 \(n_e/n_H = 1.2\) 的 composition factor。这与 Ueda+2022 的处理不同。

Code
graph TD
    A["73 southern fields<br/>b < -30 deg"] --> B["Empirical disk<br/>n0=0.0081, z0=1.60 kpc"]
    A --> C["Adiabatic halo<br/>Fang+2013 polytrope in NFW"]
    B --> D["EM = ∫(n_d+n_h)² ds<br/>cross term retained"]
    C --> D
    D --> E["chi2 = 71.7/70<br/>catalog closure verified"]
    E --> F["Extrapolate to M31<br/>b ≈ -21.6 deg (outside domain)"]

graph TD
    A["73 southern fields<br/>b < -30 deg"] --> B["Empirical disk<br/>n0=0.0081, z0=1.60 kpc"]
    A --> C["Adiabatic halo<br/>Fang+2013 polytrope in NFW"]
    B --> D["EM = ∫(n_d+n_h)² ds<br/>cross term retained"]
    C --> D
    D --> E["chi2 = 71.7/70<br/>catalog closure verified"]
    E --> F["Extrapolate to M31<br/>b ≈ -21.6 deg (outside domain)"]


3. 加载M31方向的外推数据

Code
halosat = pd.read_csv(DATA / "m31_cgmsum_halosat_kaaret2020_disk_adiabatic_halo_m31_extrapolation.csv")
print(f"Loaded {len(halosat)} M31 sightlines")
print(f"Columns: {list(halosat.columns)}")
halosat.head(8)
Loaded 14 M31 sightlines
Columns: ['obsid', 'galactic_l_deg', 'galactic_b_deg', 'nh_hi4pi_1e22_cm-2', 'outside_halosat_fit_domain', 'nominal_em_cm-6_pc', 'no_cross_term_em_cm-6_pc', 'absorbed_0p5_2p0_flux_per_em_fluxunit', 'nominal_absorbed_0p5_2p0_fluxunit', 'no_cross_term_absorbed_0p5_2p0_fluxunit', 'patchiness_sigma_absorbed_0p5_2p0_fluxunit', 'measurement_staterr_absorbed_0p5_2p0_fluxunit']
obsid galactic_l_deg galactic_b_deg nh_hi4pi_1e22_cm-2 outside_halosat_fit_domain nominal_em_cm-6_pc no_cross_term_em_cm-6_pc absorbed_0p5_2p0_flux_per_em_fluxunit nominal_absorbed_0p5_2p0_fluxunit no_cross_term_absorbed_0p5_2p0_fluxunit patchiness_sigma_absorbed_0p5_2p0_fluxunit measurement_staterr_absorbed_0p5_2p0_fluxunit
0 800730201 119.831752 -19.888005 0.057791 True 0.011788 0.009136 48.748698 0.574630 0.445350 0.165746 0.136534
1 800730301 119.508203 -20.173004 0.057602 True 0.011785 0.009135 48.788971 0.574983 0.445679 0.165883 0.122502
2 800730501 119.959338 -20.297171 0.055286 True 0.011722 0.009089 49.284947 0.577710 0.447959 0.167569 0.141052
3 800730601 120.221879 -19.978270 0.057930 True 0.011735 0.009098 48.719218 0.571719 0.443229 0.165645 0.187279
4 800730701 120.355845 -20.368759 0.057273 True 0.011672 0.009053 48.859083 0.570276 0.442322 0.166121 0.175246
5 800730801 120.090295 -20.632593 0.055956 True 0.011666 0.009050 49.140924 0.573293 0.444720 0.167079 0.435051
6 800730901 119.868483 -20.906513 0.055921 True 0.011655 0.009043 49.148343 0.572835 0.444437 0.167104 0.121189
7 800731101 120.520910 -20.803429 0.056700 True 0.011602 0.009003 48.981375 0.568259 0.440995 0.166537 0.631616

数据包含14条M31方向的XMM视场。每条视场有:

列名 含义
obsid XMM-Newton 观测ID
galactic_l_deg, galactic_b_deg 场中心的银道坐标
nh_hi4pi_1e22_cm-2 HI4PI 中性氢柱密度(\(10^{22}\) cm\(^{-2}\)
outside_halosat_fit_domain 是否在HaloSat拟合域外(全部为True)
nominal_em_cm-6_pc nominal(含交叉项)EM(cm\(^{-6}\) pc)
no_cross_term_em_cm-6_pc 去交叉项的 EM(structural check)
absorbed_0p5_2p0_flux_per_em_fluxunit 单位 EM 对应的 absorbed 0.5–2.0 keV flux
nominal_absorbed_0p5_2p0_fluxunit nominal absorbed 0.5–2.0 keV brightness(Figure 3 单位)
no_cross_term_absorbed_0p5_2p0_fluxunit 去交叉项的 absorbed brightness
patchiness_sigma_absorbed_0p5_2p0_fluxunit patchiness scatter 转换后的 1σ
measurement_staterr_absorbed_0p5_2p0_fluxunit 观测统计误差(用于权重计算)

4. 为什么这是”域外外推”?

4.1 HaloSat 的拟合域 vs M31 的位置

HaloSat 的73个拟合场全部在 \(b < -30^\circ\) 的南天高银纬区域。M31 在 \(b \approx -21.6^\circ\),十四场全部位于拟合域外。最近的一个拟合场中心距 M31 约 17.70°,超过了 HaloSat 约 7° 的零响应半径。

Code
# Verify all 14 M31 fields are outside the fit domain
all_outside = halosat["outside_halosat_fit_domain"].all()
print(f"All 14 fields outside HaloSat fit domain: {all_outside}")
print(f"Galactic latitude range: [{halosat['galactic_b_deg'].min():.2f}, {halosat['galactic_b_deg'].max():.2f}] deg")
print(f"M31 is at b ≈ -21.6 deg, fit domain is b < -30 deg")
print(f"Nearest fit field center to M31: 17.70 deg (beyond ~7 deg zero-response radius)")
All 14 fields outside HaloSat fit domain: True
Galactic latitude range: [-23.17, -19.89] deg
M31 is at b ≈ -21.6 deg, fit domain is b < -30 deg
Nearest fit field center to M31: 17.70 deg (beyond ~7 deg zero-response radius)

4.2 可视化:HaloSat 拟合域与 M31 视场

Code
# Load the 73 HaloSat southern fields
halosat_fields = pd.read_csv(DATA / "m31_cgmsum_halosat_kaaret2020_southern_fields.csv")

fig, ax = plt.subplots(figsize=(8, 5), subplot_kw={"projection": None})

# Plot HaloSat 73 field centers
ax.scatter(
    halosat_fields["galactic_l_deg"],
    halosat_fields["galactic_b_deg"],
    s=18, c="#2ca6c4", alpha=0.7, edgecolor="none",
    label=f"HaloSat 73 fit fields (b < -30 deg)"
)

# Plot selection envelope boundary at b = -30
ax.axhline(-30, color="#2ca6c4", linestyle="--", linewidth=1.0, alpha=0.5)

# Plot 14 M31 fields
ax.scatter(
    halosat["galactic_l_deg"],
    halosat["galactic_b_deg"],
    s=60, c="#e07b3a", alpha=0.9, edgecolor="white", linewidth=0.5,
    label=f"14 M31 XMM fields (b ≈ -21.6 deg)",
    zorder=5
)

# M31 center
ax.scatter(121.17, -21.57, marker="*", s=200, c="#b74842", edgecolor="white",
           linewidth=0.8, zorder=6, label="M31 center")

ax.set_xlabel("Galactic longitude l (deg)")
ax.set_ylabel("Galactic latitude b (deg)")
ax.set_title("HaloSat fit domain vs M31 footprint")
ax.legend(fontsize=9, loc="lower left")
ax.set_xlim(60, 130)
ax.set_ylim(-85, 5)
plt.show()

HaloSat 73-field fit domain (b < -30 deg, cyan) vs 14 M31 XMM fields (orange). M31 (red star) lies outside the fit domain. The nearest fit center is 17.70 deg away.

关键观察: - 73个青色点是 HaloSat 实际拟合的场中心,不是连续的天空覆盖。 - 橙色点是14个M31 XMM视场,全部在 \(b=-30^\circ\) 边界(青色虚线)之上——即拟合域外。 - 红色五角星是M31中心,最近的一个青色点离它约17.7°。


5. 第一步:模型投影到M31视线

5.1 物理原理

要把 HaloSat 的三维密度模型投影到 M31 方向,需要沿每条M31视线积分 \((n_d + n_h)^2\)

  1. 积分路径:从太阳位置(\(R_\odot = 8.0\) kpc)沿视线积分到 260 kpc;
  2. |z| 对称:盘密度使用 \(|z|\) 实现银道面对称;
  3. catalog-closed convention:保留 disk-halo 交叉项,即 \(\int(n_d+n_h)^2 ds\),不是 \(\int n_d^2 ds + \int n_h^2 ds\)

5.2 验证:nominal vs no-cross-term

Code
# The nominal branch retains the cross term; the no-cross-term is a structural check
print("Emission measure comparison (cm^-6 pc):")
print(f"  Nominal (with cross term):      mean = {halosat['nominal_em_cm-6_pc'].mean():.6f}")
print(f"  No cross term (structural chk): mean = {halosat['no_cross_term_em_cm-6_pc'].mean():.6f}")
print(f"  Ratio (nominal / no-cross):      mean = {(halosat['nominal_em_cm-6_pc'] / halosat['no_cross_term_em_cm-6_pc']).mean():.4f}")
print()
print("The cross term adds ~29% to the EM, confirming it is retained in the nominal branch.")
Emission measure comparison (cm^-6 pc):
  Nominal (with cross term):      mean = 0.011560
  No cross term (structural chk): mean = 0.008974
  Ratio (nominal / no-cross):      mean = 1.2881

The cross term adds ~29% to the EM, confirming it is retained in the nominal branch.

6. 第二步:补充温度——为什么需要 kT=0.225 keV?

6.1 模型不预测温度

HaloSat 的密度模型只告诉我们 \(n(r)\),即气体在空间各处的密度。但要把 EM 转换成X射线 flux,还需要知道气体的温度 \(kT\)——因为温度决定了X射线谱的形状(哪些能量发射多少光子)。

问题在于:HaloSat 的 disk+halo 模型不预测M31方向的温度。它只在73个南天场各自拟合了温度,但M31在拟合域外,没有对应的拟合温度。

6.2 补充 median kT = 0.225 keV

解决方案:用 HaloSat 73场的 sample median \(kT = 0.225\) keV 作为M31方向的补充温度。这是一个合理的”代表性”温度,但必须记住它是额外假设,不是模型自带的预测。

Code
# Verify the median kT from the 73-field catalog
kt_values = halosat_fields["kt_keV"].dropna()
median_kt = kt_values.median()
print(f"HaloSat 73-field median kT = {median_kt:.3f} keV")
print(f"Adopted M31-direction kT = 0.225 keV (sample median)")
print(f"Note: This is an explicit augmentation — the density model has no M31-direction temperature prediction.")
HaloSat 73-field median kT = 0.225 keV
Adopted M31-direction kT = 0.225 keV (sample median)
Note: This is an explicit augmentation — the density model has no M31-direction temperature prediction.

7. 第三步:APEC + TBabs + HI4PI → absorbed 0.5–2.0 keV

7.1 光谱转换链

有了 EM 和温度,还需要把 intrinsic(吸收前)的发射转换成 absorbed(吸收后)的观测值。转换链是:

  1. APEC(Astrophysical Plasma Emission Code):给定 \(kT=0.225\) keV 和金属丰度 \(Z=0.3\),计算等离子体的发射谱;
  2. TBabs(Tübingen-Boulder absorption):用 Wilms 丰度和 Verner 截面计算光致电离吸收;
  3. HI4PI:每条M31视线有 field-specific 的中性氢柱密度 \(N_\mathrm{H}\)

7.2 验证:flux 与 EM 的关系

Code
# Each field has a per-EM conversion factor
fig, ax = plt.subplots(figsize=(8, 4.5))
sc = ax.scatter(
    halosat["nh_hi4pi_1e22_cm-2"],
    halosat["absorbed_0p5_2p0_flux_per_em_fluxunit"],
    c=halosat["galactic_b_deg"],
    cmap="viridis",
    s=50, edgecolor="white", linewidth=0.5,
)
cbar = fig.colorbar(sc, ax=ax)
cbar.set_label("Galactic latitude b (deg)")
ax.set_xlabel("N_H (10^22 cm^-2, HI4PI)")
ax.set_ylabel("Absorbed flux per EM (flux unit / cm^-6 pc)")
ax.set_title("Per-field APEC+TBabs conversion factor")
plt.show()

print(f"  N_H range: [{halosat['nh_hi4pi_1e22_cm-2'].min():.4f}, {halosat['nh_hi4pi_1e22_cm-2'].max():.4f}] x 10^22 cm^-2")
print(f"  Flux/EM range: [{halosat['absorbed_0p5_2p0_flux_per_em_fluxunit'].min():.2f}, {halosat['absorbed_0p5_2p0_flux_per_em_fluxunit'].max():.2f}]")
print("  Higher N_H → more absorption → lower flux per EM (softer spectrum suppressed).")

  N_H range: [0.0481, 0.0692] x 10^22 cm^-2
  Flux/EM range: [46.39, 50.87]
  Higher N_H → more absorption → lower flux per EM (softer spectrum suppressed).

7.3 重建 nominal absorbed brightness

Code
# Manual reconstruction: EM × (flux per EM) = absorbed flux
manual_nominal = halosat["nominal_em_cm-6_pc"] * halosat["absorbed_0p5_2p0_flux_per_em_fluxunit"]
csv_nominal = halosat["nominal_absorbed_0p5_2p0_fluxunit"]

print("Field-by-field reconstruction (first 5):")
for i in range(5):
    print(f"  Field {i+1}: manual={manual_nominal.iloc[i]:.6f}, CSV={csv_nominal.iloc[i]:.6f}, diff={abs(manual_nominal.iloc[i]-csv_nominal.iloc[i]):.2e}")

np.testing.assert_allclose(manual_nominal, csv_nominal, rtol=1e-6)
print("\n✓ Manual reconstruction matches CSV to < 1e-6 relative tolerance")
Field-by-field reconstruction (first 5):
  Field 1: manual=0.574630, CSV=0.574630, diff=1.44e-15
  Field 2: manual=0.574983, CSV=0.574983, diff=4.66e-15
  Field 3: manual=0.577710, CSV=0.577710, diff=4.00e-15
  Field 4: manual=0.571719, CSV=0.571719, diff=4.55e-15
  Field 5: manual=0.570276, CSV=0.570276, diff=2.11e-15

✓ Manual reconstruction matches CSV to < 1e-6 relative tolerance

8. 第四步:14场汇总到Figure 3的一个点

8.1 inverse-variance 加权

Figure 3 需要把14个视场汇成一个 all-field estimator。采用与实测 CGMsum 相同的 inverse-variance weighting(以观测统计误差为权重):

\[S_{\mathrm{all}} = \frac{\sum_i w_i S_i}{\sum_i w_i}, \quad w_i = \frac{1}{\sigma_{\mathrm{stat},i}^2}\]

8.2 计算与验证

Code
# Inverse-variance weighted average using measurement statistical errors
flux = halosat["nominal_absorbed_0p5_2p0_fluxunit"].to_numpy()
sigma = halosat["measurement_staterr_absorbed_0p5_2p0_fluxunit"].to_numpy()
weights = 1.0 / sigma**2
all_field = np.average(flux, weights=weights)

# Footprint range (min/max across 14 fields)
footprint_lo = flux.min()
footprint_hi = flux.max()

# Patchiness predictor (inverse-variance weighted mean, same weights as all-field)
patchiness = np.average(halosat["patchiness_sigma_absorbed_0p5_2p0_fluxunit"].to_numpy(), weights=weights)

# No-cross-term structural check
flux_nc = halosat["no_cross_term_absorbed_0p5_2p0_fluxunit"].to_numpy()
all_field_nc = np.average(flux_nc, weights=weights)

print(f"All-field inverse-variance prediction:  {all_field:.6f}")
print(f"14-field footprint range:               [{footprint_lo:.6f}, {footprint_hi:.6f}]")
print(f"Patchiness predictor (mean sigma):      {patchiness:.6f}")
print(f"No-cross-term structural check:         {all_field_nc:.6f}")
All-field inverse-variance prediction:  0.565386
14-field footprint range:               [0.526442, 0.577710]
Patchiness predictor (mean sigma):      0.165165
No-cross-term structural check:         0.438683

8.3 与冻结的 Figure 3 ledger 对账

Code
# Frozen Figure 3 ledger values from I023 / B014
LEDGER_ALL_FIELD    = 0.565386
LEDGER_FOOTPRINT_LO = 0.526442
LEDGER_FOOTPRINT_HI = 0.577710
LEDGER_PATCHINESS   = 0.165165
LEDGER_NO_CROSS      = 0.438683

np.testing.assert_allclose(all_field,    LEDGER_ALL_FIELD,    rtol=1e-4)
np.testing.assert_allclose(footprint_lo, LEDGER_FOOTPRINT_LO, rtol=1e-4)
np.testing.assert_allclose(footprint_hi, LEDGER_FOOTPRINT_HI, rtol=1e-4)
np.testing.assert_allclose(patchiness,   LEDGER_PATCHINESS,   rtol=1e-4)
np.testing.assert_allclose(all_field_nc, LEDGER_NO_CROSS,     rtol=1e-4)
print("✓ Matches frozen Figure 3 ledger to < 1e-4")
✓ Matches frozen Figure 3 ledger to < 1e-4

9. 可视化:14场分布与Figure 3位置

Code
fig, ax = plt.subplots(figsize=(9, 5))

# Plot each field with patchiness error bars
field_idx = np.arange(len(halosat))
ax.errorbar(
    field_idx, flux,
    yerr=halosat["patchiness_sigma_absorbed_0p5_2p0_fluxunit"],
    fmt="o", color="#2676b8", markersize=6, capsize=3, linewidth=0.8,
    label="14 M31 fields (patchiness sigma)"
)

# All-field prediction
ax.axhline(all_field, color="#d47a2c", linewidth=2, label=f"All-field prediction = {all_field:.3f}")
ax.axhspan(footprint_lo, footprint_hi, color="#d47a2c", alpha=0.12, label=f"Footprint [{footprint_lo:.3f}, {footprint_hi:.3f}]")

# Observed CGMsum total for reference
ax.axhline(0.964727, color="#b74842", linestyle="--", linewidth=1.5, label="Observed CGMsum = 0.965 (M31)")

ax.set_xlabel("Field index (0-13)")
ax.set_ylabel("Absorbed 0.5-2.0 keV brightness (10^-15 erg s^-1 cm^-2 arcmin^-2)")
ax.set_title("HaloSat extrapolation: 14 M31 fields")
ax.set_xticks(field_idx)
ax.legend(fontsize=9, loc="upper right")
plt.show()

14 M31 fields’ nominal absorbed brightness. Orange line = all-field inverse-variance prediction (0.565). Grey band = footprint range. Red dashed = observed CGMsum total (0.965). Patchiness sigma shown as error bars.

关键观察: - 14场的 nominal 预测集中在约0.53–0.58,变化不大——因为14场在天空上很接近,模型给出的EM很相似。 - All-field 预测 0.565 明显低于实测 CGMsum 总量 0.965——这说明 HaloSat 域外外推只解释了M31方向总量的一部分,剩余部分来自M31自身的CGM。 - Patchiness sigma(蓝色误差棒)约0.16,反映模型承认的南天场间不均匀性。


10. 关键假设清单(必须记住!)

步骤 假设 来源
拟合域 73个 \(b<-30^\circ\) 南天场 Kaaret+2020 catalog
EM convention \(\int(n_d+n_h)^2 ds\),保留交叉项 catalog \(\chi^2\) closure
\(n\) 的粒子身份 未定义(不乘 \(n_e/n_H=1.2\) 论文未说明
温度 \(kT=0.225\) keV(sample median) 额外补充,模型不预测M31方向温度
丰度 \(Z=0.3\) 项目统一选择
吸收 TBabs + Wilms + Verner + field-specific HI4PI 项目实现
积分路径 \(R_\odot=8.0\) kpc,0–260 kpc 内部LOS 项目实现
M31位置 \(b\approx-21.6^\circ\),全部14场在拟合域外 域外外推
证据等级 supplemental extrapolation,非直接预测 本项目定位

11. 动手练习

练习 1:验证交叉项的贡献

计算 nominal EM 与 no-cross-term EM 的比值,量化交叉项对发射量度的贡献比例。

Cross-term ratio (nominal / no-cross):
  mean = 1.2881
  std  = 0.0019

The cross term contributes ~28.8% of the EM.
Removing it would drop the absorbed flux to ~0.439 (structural check).

练习 2:N_H 与吸收的关系

计算14场的 \(N_\mathrm{H}\) 与 flux-per-EM 之间的 Pearson 相关系数。这个相关性是正还是负?为什么?

Pearson r = -0.9998
Negative — higher N_H means more absorption, so each unit of EM produces less absorbed flux.

练习 3:patchiness 的物理含义

Patchiness sigma 是什么?它和 measurement statistical error 有什么区别?

Patchiness sigma (mean): 0.16569271558482795
Measurement staterr (mean): 0.2786016613799958

Patchiness sigma reflects real spatial scatter in the southern HaloSat fields
(the model explicitly requires sigma_p ≈ 3.4e-3 cm^-6 pc of EM scatter).
Measurement staterr is the observational uncertainty of each M31 field.
They are independent sources of spread: one is model-intrinsic, one is instrumental.

12. 总结:从HaloSat拟合到Figure 3的完整链路

Code
graph TD
    A["HaloSat 73 southern fields<br/>b < -30 deg, EM + kT fitted"] --> B["Empirical disk<br/>n0=0.0081, z0=1.60 kpc"]
    A --> C["Adiabatic halo<br/>Fang+2013 in NFW potential"]
    B --> D["EM = ∫(n_d+n_h)² ds<br/>cross term retained, no n_e/n_H factor"]
    C --> D
    D --> E["Project to 14 M31 sightlines<br/>R_sun=8.0 kpc, 0-260 kpc, |z|"]
    E --> F["Augment kT=0.225 keV<br/>(model has no M31-direction T)"]
    F --> G["APEC(Z=0.3) × TBabs × HI4PI<br/>→ absorbed 0.5-2.0 keV"]
    G --> H["14-field inverse-variance average<br/>= 0.565 (Figure 3 point)"]
    H --> I["Supplemental extrapolation<br/>NOT a direct HaloSat prediction"]

graph TD
    A["HaloSat 73 southern fields<br/>b < -30 deg, EM + kT fitted"] --> B["Empirical disk<br/>n0=0.0081, z0=1.60 kpc"]
    A --> C["Adiabatic halo<br/>Fang+2013 in NFW potential"]
    B --> D["EM = ∫(n_d+n_h)² ds<br/>cross term retained, no n_e/n_H factor"]
    C --> D
    D --> E["Project to 14 M31 sightlines<br/>R_sun=8.0 kpc, 0-260 kpc, |z|"]
    E --> F["Augment kT=0.225 keV<br/>(model has no M31-direction T)"]
    F --> G["APEC(Z=0.3) × TBabs × HI4PI<br/>→ absorbed 0.5-2.0 keV"]
    G --> H["14-field inverse-variance average<br/>= 0.565 (Figure 3 point)"]
    H --> I["Supplemental extrapolation<br/>NOT a direct HaloSat prediction"]

一句话总结:Kaaret et al. (2020) 用 HaloSat 的73个南天场拟合出银河系热气体的 empirical disk + adiabatic halo 三维模型。这个模型沿M31方向14条视线外推积分,补充 sample-median 温度后转换为 absorbed 0.5–2.0 keV brightness,得到 all-field 预测 0.565——这是一个 supplemental domain extrapolation,不是 HaloSat 对M31方向的直接预测,因为M31完全在拟合域外。


参考资料

  1. Kaaret, P. et al. (2020). “A disk-dominated and clumpy circumgalactic medium of the Milky Way seen in X-ray emission.” Nature Astronomy, 4, 1072–1077. doi:10.1038/s41550-020-01215-w
  2. CDS catalog J/other/NatAs/4.1072 — VizieR link
  3. Fang, T. et al. (2013). Adiabatic polytropic CGM model in NFW potential.
  4. HI4PI Collaboration (2016). “HI4PI: A full-sky H I line survey.” A&A, 594, A116.
  5. Bluem, J. et al. (2022). “HaloSat’s 156-field two-temperature catalog.” ApJ.

教程结束 🎓 下一步:继续阅读 Ueda+2022 tutorial,了解 in-domain disk model 如何在M31 footprint内直接投影。