首页
/ astropy.cosmology 宇宙学计算完全指南:内置模型、距离/时间/密度换算与红移逆推(scientific-agent-skills 技能解析)

astropy.cosmology 宇宙学计算完全指南:内置模型、距离/时间/密度换算与红移逆推(scientific-agent-skills 技能解析)

2026-09-08 19:17:07作者:侯霆垣

astropy.cosmology 是 Astropy 生态中专用于宇宙学计算的子包,它基于标准宇宙学模型(ΛCDM 及其变体)为距离、年龄、哈勃参数、密度参数、巡天体积累计等提供统一且带单位的 API。本文是 scientific-agent-skills 仓库中 astropy 技能 的参考文档 cosmology.md 的深度展开,面向需要"把观测红移换算成物理量"的天文数据处理与 Agent 编程场景。读完本文,你将掌握:直接使用 Planck/WMAP 内置宇宙学、手工构造 FlatLambdaCDM/w0wzCDM 等自定义模型、调用全套距离与时间方法、用 z_at_value 反解红移,以及大规模数组运算与中微子参数的正确打开方式。

适用场景:何时需要用到这一子包

在 Astropy 技能定义的典型天文工作流中(见 SKILL.md),凡是任务涉及下列环节,都应该优先想到 astropy.cosmology

  • 把谱线红移、星系退行速度换算为光度距离、同动距离等物理距离;
  • 由红移计算宇宙年龄、回溯时间(lookback time)等时间量;
  • 求某红移处的哈勃参数 H(z) 与各密度参数随红移的演化;
  • 为巡天项目估算两个红移面之间的宇宙学体积(如单位化为 Gpc³);
  • 用测光红移 + 视星等反推绝对星等,或由角大小估算天体物理尺度。

换句话说,只要代码里出现"给定 z,我需要一个带单位的距离/年龄/体积",这个子包就是标准答案。它输出的所有量都是 astropy.units.Quantity(带物理单位),天然与仓库中另一份参考 units.md 描述的单位系统无缝衔接,避免手工换算和维度错误。

安装与环境约定

astropy.cosmology 随 Astropy 主包一起分发,因此安装即用。仓库当前调研到的稳定版本约束如下(见 SKILL.md):

# 可复现安装:锁定当前稳定版本 7.2.0
uv pip install "astropy==7.2.0"

# 推荐可选依赖(绘图与常见科学工作流)
uv pip install "astropy[recommended]==7.2.0"

# 完整可选依赖(宽泛天文工作流)
uv pip install "astropy[all]==7.2.0"

环境要求是 Python 3.11+,并依赖 NumPy、PyERFA、PyYAML、packaging 等底层库;建议在独立虚拟环境中安装,不要用提权方式安装。注意 [recommended][all] 会带入 matplotlib、scipy 等传递依赖且不锁版本,生产环境建议用 uv lock / uv pip compile 固定整棵依赖树。

关于导入路径的重要提示

astropy.cosmology 的公开类与函数在旧版本中散落在 astropy.cosmology.flrw.core.funcs.connect.parameter 等子模块。这些旧子模块导入路径自 Astropy 7.1 起被弃用,并将在 Astropy 8.0 中被正式移除(仓库文档在 SKILL.md 的版本说明中明确标注了 8.0 的移除计划)。因此,本参考文档中的所有示例都坚持一种写法:

# 正确:一律从顶层 astropy.cosmology 导入
from astropy.cosmology import FlatLambdaCDM, Planck18, z_at_value

新代码不要再写 from astropy.cosmology.flrw import FlatLambdaCDM 之类的旧路径,否则迁移到 8.x 时会直接报导入错误。

直接使用内置宇宙学:Planck18 与 WMAP 系列

无需自己指定任何参数,astropy.cosmology 预置了基于 WMAP 与 Planck 观测结果的常用宇宙学实例,开箱即用:

from astropy.cosmology import Planck18, Planck15, Planck13
from astropy.cosmology import WMAP9, WMAP7, WMAP5
from astropy import units as u

# 选用 Planck 2018 结果作为默认宇宙学
cosmo = Planck18

# 计算 z=4 处的光度距离
d = cosmo.luminosity_distance(4)
print(f"Luminosity distance at z=4: {d}")

# 当前宇宙年龄(z=0)
age = cosmo.age(0)
print(f"Current age of universe: {age.to(u.Gyr)}")

这些实例各自封装了一组具体的实测参数(哈勃常数、物质密度等)。实际项目里,不同论文、不同数据版本(Planck 2013/2015/2018,或 WMAP 5/7/9 年)采用的宇宙学参数并不相同,直接选用对应实例能在比较不同研究结果时保持口径一致。当你只是"想算一个距离",应优先用这些内置实例,而不是手写参数。

构建自定义宇宙学模型

当内置实例不满足需求(例如采用你自己的 H0Om0,或需要暗能量状态方程参数)时,可以用模型类构造自定义实例。

FlatLambdaCDM(最常用):平坦 + 宇宙学常数

假定宇宙空间平坦(曲率项为 0),暗能量为宇宙学常数:

from astropy.cosmology import FlatLambdaCDM
from astropy import units as u

cosmo = FlatLambdaCDM(
    H0=70 * u.km / u.s / u.Mpc,  # z=0 时的哈勃常数(必填)
    Om0=0.3,                      # z=0 时的物质密度参数(必填)
    Tcmb0=2.725 * u.K             # 当前 CMB 温度(可选,默认即 2.725 K)
)

参数语义:

  • H0:红移 0 处的哈勃常数,量纲为速度/距离,通常写为 70*u.km/u.s/u.Mpc。它决定了宇宙的膨胀标度,直接影响所有距离与年龄的数值。
  • Om0:当前物质(重子 + 暗物质)总密度参数 Ωm0,无量纲。
  • Tcmb0(可选):当前 CMB 温度,默认 2.725 K;提供它后模型才会计算光子与中微子密度项(见下文 Ogamma/Onu)。
  • 在平坦模型中,暗能量密度参数由平坦性条件 Ode0 = 1 - Om0 隐含决定,无需也不能再传 Ode0

LambdaCDM(非平坦):显式给定暗能量密度

若允许曲率不为零,则需同时显式给出物质与暗能量密度:

from astropy.cosmology import LambdaCDM

cosmo = LambdaCDM(
    H0=70 * u.km / u.s / u.Mpc,
    Om0=0.3,
    Ode0=0.7   # 当前暗能量密度参数;此时曲率密度由 1 - Om0 - Ode0 隐含
)

wCDM 与 w0wzCDM:带状态方程的暗能量

当需要把暗能量建模为"非宇宙学常数"(状态方程参数 w ≠ -1)时:

from astropy.cosmology import FlatwCDM, w0wzCDM

# 恒定 w:暗能量状态方程 p = w·ρc²,w 不随红移变化
cosmo_w = FlatwCDM(H0=70 * u.km / u.s / u.Mpc, Om0=0.3, w0=-0.9)

# w 随红移线性演化:w(z) = w0 + wz * z
cosmo_wz = w0wzCDM(H0=70 * u.km / u.s / u.Mpc, Om0=0.3, Ode0=0.7,
                   w0=-1.0, wz=0.1)

要点:

  • w0:z=0 处的状态方程参数。w = -1 时退化为宇宙学常数;w > -1(如 -0.9)代表"精质"型暗能量,w < -1 对应"幻影"型。
  • wzw0wzCDM 的演化斜率,给出 w(z) = w0 + wz·z 的线性模型。
  • 注意 w0wzCDM 在平坦场景中构造方式类似(用 Flatw0waCDM 等变体承接平坦约束),文档示例给出的非平坦形式要求同时传 Ode0,与 LambdaCDM 的约束逻辑一致。

无论哪类模型,一旦实例化,下面所有距离、时间、密度方法均可统一调用——这是该子包最重要的设计:方法接口与模型实现解耦

距离计算全家桶

观测宇宙学的核心任务之一就是做距离换算。模型对象对每个 z 都能给出多个定义不同的"距离",各自服务于不同物理场景。以下方法均接受标量或数组 z,返回带单位的量。

同动距离(Comoving Distance)

沿视线方向的同动距离,是其他大多数距离的基础:

d_c = cosmo.comoving_distance(z)

它度量的是"如果宇宙今天停止膨胀,光走过的路径长度",红移只源于膨胀本身。

光度距离(Luminosity Distance)

由观测通量反推天体光度时使用,是超新星 Ia 测距、绝对星等计算的标准距离:

d_L = cosmo.luminosity_distance(z)

# 由视星等求绝对星等:M = m - 5·log10(d_L/pc) + 5
M = m - 5*np.log10(d_L.to(u.pc).value) + 5

公式中 d_L 必须先转换到 pc(秒差距)再取 value 参与对数运算——这正是带单位 Quantity 的便利之处:.to(u.pc) 完成单位换算,.value 取出纯数值。

角直径距离(Angular Diameter Distance)

由角大小估算物理尺寸时使用。它描述"同一固有尺度在不同红移处看起来多大":

d_A = cosmo.angular_diameter_distance(z)

# 由角大小求物理尺寸(弧度制乘法)
theta = 10 * u.arcsec   # 角大小
physical_size = d_A * theta.to(u.radian).value

注意角大小必须先转到弧度(theta.to(u.radian))再与距离相乘。在任意几何中,角直径距离与同动距离满足 D_A = D_M/(1+z)D_M 为同动横向距离),因此高红移处角直径距离会"由增转减",这是宇宙学角直径关系的著名特征。

同动横向距离(Comoving Transverse Distance)

在平坦宇宙中它与同动距离相等;非平坦模型中则需要它来正确描述横向尺度:

d_M = cosmo.comoving_transverse_distance(z)

angular_diameter_distance 正是由它除以 (1+z) 得到。

距离模数(Distance Modulus)

dm = cosmo.distmod(z)
# 满足 m - M = dm(视星等 - 绝对星等)

distmod 返回 Quantity(单位为星等 mag),直接写成 m_app - cosmo.distmod(z).value 即可从视星等得到绝对星等,比手动写 5*log10(...) + 25 更不易错。

尺度与体积换算

巡天设计、透镜统计、团簇丰度研究常需要"角尺度 ↔ 物理尺度""单位红移厚度内有多少体积"这类换算:

# 某红移处 1 角分对应的物理 kpc(估算角分辨率对应尺度非常常用)
scale = cosmo.kpc_proper_per_arcmin(z)
# 例:z=1 附近输出形如 "≈50 kpc/arcmin" 的物理量

# 到红移 z 为止的累计同动体积
vol = cosmo.comoving_volume(z)

# 微分同动体积 dV/dz(单位红移厚度的体积)
vol_element = cosmo.differential_comoving_volume(z)

kpc_proper_per_arcmin 返回的是"某时刻该红移处的固有尺度";而 comoving_volume 把整个视锥体积累加出来,是巡天完备性计算与数密度估计的基础。二者都直接返回带单位量,后续单位化(如转 Gpc³)只需 .to(u.Gpc**3)

时间计算:宇宙年龄与回溯时间

宇宙年龄(Age of Universe)

任意红移处宇宙的年龄(即从大爆炸到该红移时刻所经历的时间):

age = cosmo.age(z)        # 红移 z 处的宇宙年龄
age_now = cosmo.age(0)    # 当前年龄
age_at_z1 = cosmo.age(1)  # z=1 时的年龄

回溯时间(Lookback Time)

光子从发射到被我们接收"走过了多少宇宙时间",即 z 与 0 之间的年龄差:

t_lookback = cosmo.lookback_time(z)
# 数值上约等于 age(0) - age(z)

lookback_time 是星系演化研究中最常用的量——观测高红移天体等于"回看"宇宙更年轻的时期,把观测到的红移 z 换成回溯时间,能直观给出"我们看到的是多少亿年前的光"。

哈勃参数与无量纲膨胀因子

任意红移处的膨胀速率:

H_z = cosmo.H(z)       # H(z),单位 km/s/Mpc
E_z = cosmo.efunc(z)   # E(z) = H(z)/H0(无量纲,H0 已折出)

efunc 在数值积分中大量使用:因为 H(z) = H0·E(z),把 E(z) 提出来可以显著改善积分条件数,也是代码中手写弗里德曼方程、验证距离积分正确性的好抓手。

密度参数随红移的演化

模型可以给出各组分密度参数在任何 z 处的取值,用于检查某红移处宇宙的组分构成(例如物质主导期、暗能量主导期的划分):

Om_z = cosmo.Om(z)          # 物质(重子+暗物质)密度参数
Ode_z = cosmo.Ode(z)        # 暗能量密度参数
Ok_z = cosmo.Ok(z)          # 曲率密度参数(平坦宇宙恒为 0)
Ogamma_z = cosmo.Ogamma(z)  # 光子(辐射)密度参数
Onu_z = cosmo.Onu(z)        # 中微子密度参数

这些方法对任一组分都保证 Om+Ode+Ok+Ogamma+Onu = 1(误差范围内)。OgammaOnu 只有在构造时给出 Tcmb0(以及 Neff/m_nu,见下文)才会是可靠的非零值——因此构造模型时别省略 Tcmb0=2.725*u.K 这一行。

临界密度与物质密度

rho_c = cosmo.critical_density(z)             # 临界密度 ρc(z)
rho_m = cosmo.critical_density(z) * cosmo.Om(z)  # 物质密度 = ρc · Ωm

临界密度是区分宇宙几何"开/平/闭"的标尺;乘以对应密度参数即得绝对质量密度。比如估算暗物质晕的质量函数、把数密度换算成质量密度时,critical_density 是必经中间量。

红移逆推:z_at_value

正向方法都是"给 z 求物理量"。反过来,当已知目标物理量(如某个回溯时间、某段光度距离)需要求对应的红移 z 时,用 z_at_value

from astropy.cosmology import z_at_value

# 找到回溯时间为 10 Gyr 对应的 z
z = z_at_value(cosmo.lookback_time, 10*u.Gyr)

# 找到光度距离为 1000 Mpc 对应的 z
z = z_at_value(cosmo.luminosity_distance, 1000*u.Mpc)

# 找到宇宙年龄为 1 Gyr 对应的 z(即"宇宙只有 10 亿岁时对应红移多少")
z = z_at_value(cosmo.age, 1*u.Gyr)

用法要点:

  • 第一个参数传方法对象本身(如 cosmo.lookback_time),第二个参数传目标量(务必带单位);
  • 由于距离/时间随 z 单调(大部分区间),该方法通过数值求根定位 z,因此要求目标值落在该函数取值范围内;
  • 属于相对昂贵的数值运算,若要在循环中反复调用,建议先算好再复用(与 SKILL.md 中"缓存频繁使用的昂贵计算结果"的最佳实践一致)。

数组运算:一次性处理整批红移

所有方法都对 NumPy 数组原生支持且已向量化,不必写 Python 循环:

import numpy as np

z_array = np.linspace(0, 5, 100)          # 0 到 5 之间均匀取 100 个红移
d_L_array = cosmo.luminosity_distance(z_array)  # 光度距离数组
H_array = cosmo.H(z_array)                # 哈勃参数数组
age_array = cosmo.age(z_array)            # 年龄数组

输入标量返回标量 Quantity,输入数组返回同形状的 Quantity 数组。画 D_L(z)H(z)age(z) 关系曲线、或对一批测光红移做批量换算时,这种用法既简洁又高效。

中微子效应:Neff 与 m_nu

当精度要求高(例如拟合 CMB 或做高精度距离比较)时,可以纳入大质量中微子的影响:

from astropy.cosmology import FlatLambdaCDM
from astropy import units as u

cosmo = FlatLambdaCDM(
    H0=70 * u.km/u.s/u.Mpc,
    Om0=0.3,
    Tcmb0=2.725 * u.K,
    Neff=3.04,              # 有效中微子代数(标准值 3.04)
    m_nu=[0., 0., 0.06] * u.eV   # 三种味中微子的质量
)

参数说明:

  • Neff:有效相对论性自由度,标准模型取 3.04(略大于 3 源于微小的非瞬时退耦效应)。
  • m_nu:三味(电子、μ、τ)中微子质量数组,必须用 u.eV 标注单位。非零质量使中微子从辐射样演化为物质样,从而微调各 z 处的距离与年龄。

性能权衡:纳入大质量中微子后,模型中的若干积分需要处理更复杂的动量/质量依赖,据参考文档的经验提示,计算速度会下降约 3–4 倍,但换来更精确的结果。取舍策略是:常规工程估算用无质量中微子;只有需要与精密宇宙学数据对齐时才开启 m_nu

不可变性:克隆并修改模型

模型对象是不可变的——构造后不能原地改 H0 等参数。需要参数微调时用 clone 生成副本:

# 复制并更换 H0
cosmo_new = cosmo.clone(H0=72 * u.km/u.s/u.Mpc)

# 复制并重命名(便于日志与结果标注)
cosmo_named = cosmo.clone(name="My Custom Cosmology")

clone 只会改动传入的关键字参数,其余沿用原模型。做参数扫描(如检验 H0 不确定性对距离的影响)时,这一模式比反复从零构造更清晰。

高频实战案例组合

由视星等与红移计算绝对星等

z = 1.5
m_app = 24.5                    # 视星等
d_L = cosmo.luminosity_distance(z)
M_abs = m_app - cosmo.distmod(z).value   # 绝对星等(星等单位做减法,取纯数值)

巡天体积估算(两红移面之间)

z_min, z_max = 0.5, 1.5
volume = cosmo.comoving_volume(z_max) - cosmo.comoving_volume(z_min)  # 壳体体积

# 单位化为 Gpc³ 便于报告
volume_gpc3 = volume.to(u.Gpc**3)

由角大小求物理尺寸

theta = 1 * u.arcsec            # 角大小
z = 2.0
d_A = cosmo.angular_diameter_distance(z)
size_kpc = (d_A * theta.to(u.radian)).to(u.kpc)   # 直接得到带单位尺寸

(注意与上文中使用 .value 的写法对比:若想保持全程带单位,就做量纲相乘后用 .to(u.kpc);若中途要进入对数/标量公式,则先 .value。两种风格各有适用场景。)

天体形成以来经过的时间

z_formation = 6
age_at_formation = cosmo.age(z_formation)   # 该红移处宇宙年龄
time_since_formation = cosmo.age(0) - age_at_formation  # 从形成到现在的时间

不同模型结果对比

from astropy.cosmology import Planck18, WMAP9

z = 1.0
print(f"Planck18 d_L: {Planck18.luminosity_distance(z)}")
print(f"WMAP9 d_L: {WMAP9.luminosity_distance(z)}")

把多个内置实例并排调用同一方法,即可量化宇宙学参数选择带来的系统差(例如 Planck18 与 WMAP9 的 H0 取值不同,会导致距离差若干百分点)。这类对比是研究论文中"宇宙学假设影响"讨论的标准写法。

性能要点与有效范围

综合参考文档与技能最佳实践,使用时请注意:

  • 常规计算很快:对大多数单点 z 计算,开销可忽略;整套接口面向交互与批量场景设计。
  • 中微子是主要减速项:开启 m_nu 后慢 3–4 倍,批量大数组时尤其明显。
  • 数组已向量化:优先把 z 组织成数组一次算完,而不是在 Python 循环里逐点调用。
  • 结果有效范围:各方法在 z ≲ 5000–6000 内有效(具体上限依模型而定,辐射主导极早期的高 z 外推需谨慎)。超出范围或需要极高精度时,应核对官方 API 说明与数值积分假设。
  • 昂贵结果值得缓存:若同一 z 集合会被多处复用(重复画图、多次对比),先算好 Quantity 数组缓存起来,避免重复积分。

与技能内其他参考的配合使用

astropy.cosmology 通常不是孤立使用的:真实工作流往往是"读表/读 FITS → 坐标变换 → 用单位做量纲换算 → 宇宙学距离/时间换算"。在 scientific-agent-skills 的 astropy 技能内部,本文对应的参考文档与以下文件配合可覆盖完整链路:

  • units.md:本文所有返回值的单位换算、.to()、星等/对数单位等底层能力;
  • coordinates.md:天球坐标与红移观测量的坐标变换;
  • tables.md:批量星表(含红移列)的读写、过滤与匹配,是"对一列 z 批量算距离"的常见前置;
  • fits.md:从 FITS 星表/图像读出红移或距离相关数据;
  • SKILL.md:技能入口,含完整快速上手示例、安装与环境、网络访问注意事项与版本说明。

版本方面再次提醒:以 Astropy 7.2.0 为准(Python 3.11+),并关注 8.0 发布后对旧 astropy.cosmology.* 子模块 shim 的移除——从现在起坚持从 astropy.cosmology 顶层导入,即可平滑迁移到未来版本。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391