开发人员的宇宙学#

函数中的宇宙论#

假设一个默认的宇宙学通常是有用的,这样就不必在每次调用函数或方法时都指定确切的宇宙学。在这种情况下,可以指定一个“默认的”宇宙学。

中的“Default_Cosmology”选项将默认宇宙设置为预定义的值。 [cosmology.core] 部分配置文件(请参见 配置系统 (astropy.config ) )。或者,您可以使用 set() 的功能 default_cosmology 为当前的Python会话设置宇宙学。如果您尚未使用上述方法之一设置默认宇宙学,则宇宙学模块将默认使用 default_cosmology._value 参数。

您可以通过以下方式覆盖默认宇宙学 default_cosmology Science State对象,使用类似以下内容:

from astropy.cosmology import default_cosmology

def myfunc(..., cosmo=None):
    if cosmo is None:
        cosmo = default_cosmology.get()

    ... function code here ...

这可以确保所有代码一致地使用默认的宇宙学,除非显式重写。

备注

如果您正在准备一篇论文,因此需要确保您的代码提供可重现的结果,则最好使用明确的宇宙论(例如 WMAP9.H(0) 而不是 default_cosmology.get().H(0) )。默认宇宙学的使用通常应保留给允许改变全局宇宙学状态的代码;例如, astropy 核心或附属程序包。

定制宇宙学#

在……里面 astropy.cosmology 宇宙是类,因此定制宇宙可以通过子类化来实现 Cosmology (或者更有可能 FLRW ),并添加特定于该宇宙学的细节。在这里,我们将回顾其中的一些细节、技巧和技巧,以构建一门高性能的宇宙学课程。

from astropy.cosmology import FLRW

@dataclass(frozen=True, eq=False)
class CustomCosmology(FLRW):
    ...  # [details discussed below]

参数#

像星座一样 Cosmology 它的特征是1)它的类,它编码物理,2)它的自由参数(S),它指定了一种宇宙学的实现。定义前者时,所有参数都必须使用 Parameter 并且应该在实例化时赋值。

A Parameter 是一种 descriptor 。当从类访问时,它透明地存储信息,如单元和接受的等价物,这些信息可能不透明地包含在构造函数签名中,或者更深入地包含在代码中。在宇宙学实例中,描述符将返回参数值。

有许多最佳实践。作为参考,它摘自 FLRW

@dataclass(frozen=True, eq=False)
class FLRW(Cosmology):

    H0: Parameter = Parameter(doc="Hubble constant as an `~astropy.units.Quantity` at z=0",
                              unit="km/(s Mpc)", fvalidate="scalar")
    Om0: Parameter = Parameter(doc="Omega matter; matter density/critical density at z=0",
                               fvalidate="non-negative")
    Ode0: Parameter = Parameter(doc="Omega dark energy; dark energy density/critical density at z=0.",
                                fvalidate="float")
    Tcmb0: Parameter = Parameter(doc="Temperature of the CMB as `~astropy.units.Quantity` at z=0.",
                                 default=0.0 * u.K, unit="Kelvin", fmt="0.4g", fvalidate="scalar")
    Neff: Parameter = Parameter(doc="Number of effective neutrino species.",
                                default=3.04, fvalidate="non-negative")
    m_nu: Parameter = Parameter(doc="Mass of neutrino species.",
                                default=0.0*u.eV, unit="eV", equivalencies=u.mass_energy(), fmt="")
    Ob0: Parameter = Parameter(doc="Omega baryon; baryonic matter density/critical density at z=0.",
                               default=None)

    @Ob0.validator
    def Ob0(self, param, value):
        """Validate baryon density to None or positive float > matter density."""
        if value is None:
            return value
        value = _validate_non_negative(self, param, value)
        if value > self.Om0:
            raise ValueError("baryonic density can not be larger than total matter density.")
        return value

首先请注意,所有参数也都是 __init__() 。严格来说,这并不是必须的,但这是很好的做法。如果参数有单位(和相关的等效单位),则必须在 Parameter ,如中“H0”项所示 parameters

下一件需要注意的重要事情是如何设置参数值,在 __init__Parameter 允许设置一次值(在自动锁定之前),因此 self.H0 = H0 将使用此设置器并将值设置为“._H0”。与直接分配给私有属性相比,这种方法的优势在于使用了验证器。 Parameter 允许自定义值验证器,使用方法修饰符 validator ,它可以检查值的有效性并修改该值,例如分配单位。如果没有定制 validator 默认情况下,检查 Parameter 已定义单位,如果已定义,则将值作为 Quantity 在这些单位的情况下,使用全部启用和参数的单位等效值。

最后需要注意的是, Cosmology 。每个 Parameter 默认设置为 format specification “.3g”,但此选项可能会被覆盖,如 Tcmb0 的确如此。

如果新的宇宙学修改了现有的参数,那么 clone() 方法对于深入复制参数和更改任何构造函数参数非常有用。例如,请参见 FlatFLRWMixin 在……里面 astropy.cosmology.flrw (也如下所示)。

@dataclass(frozen=True, eq=False)
class FlatFLRWMixin(FlatCosmologyMixin):
    ...

    Ode0: Parameter = FLRW.parameters["Ode0"].clone(derived=True)

混合食品#

Mixins 用于 cosmology 跨不同继承线中的多个类重用代码。我们松散地使用这个术语,因为混合应该是严格正交的,但可能不是,特别是在 __init__

目前唯一的混合是 FlatCosmologyMixin 以及它的 FLRW -特定子类 FlatFLRWMixin 。“平坦的”宇宙学应该使用这种混合。 FlatFLRWMixin 必须在多重继承中位于基类之前,以便此混合的 __init__ 继续基类。

加速自定义宇宙中的积分#

提供的宇宙学课程使用一些技巧来加速距离和时间积分。任何人都没有必要将子类化 FLRW 使用这些技巧--但如果他们这样做了,这样的计算可能会快得多。

第一个,也是更基本的想法是,在许多情况下,为以下问题提供明确的公式是一件大事 inv_efunc() 不是简单地设置 de_energy_scale --假设有一个很好的表达。如上所述,几乎所有提供的类都是这样做的,并且该模板之后几乎可以直接进行适当的公式更改。

第二个也是更高级选项是还显式地提供仅标量版本的 inv_efunc() 。这会在距离和年龄积分方面产生相当大的加速比(大多数情况下超过10倍),即使只在Python语言中执行,因为测试输入是可迭代的还是纯标量的代价相当高。要利用这一点,关键是显式设置实例变量 self._inv_efunc_scalarself._inv_efunc_scalar_args 在子类的构造函数中,其中后者是除 z_inv_efunc_scalar 。所提供的类确实使用了这种优化,实际上甚至更进一步,提供了对无辐射和使用Cython编码的无质量中微子进行辐射的优化。请查阅 FLRW 子类和 scalar_inv_efuncs 详情请看。

然而,重要的一点是,它是 not 做这件事是必要的。

Astroy互操作性:I/O和您的宇宙学包#

如果您正在开发一个包,并且希望能够与 Cosmology ,你来对地方了!在这里,我们将讨论如何使Astropy能够读写您的文件格式,并将您的宇宙学对象与Astropy的对象相互转换 Cosmology

以下内容假定您了解Astroy结构I/O的工作原理。有关快速教程,请参阅 宇宙学I/O与转换

现在我们已经知道如何在|Cosmology.Read|、|Cosmology.Write||Cosmology.from_Format||Cosmology.To_Format|中构建和注册函数,我们可以在您的程序包中执行此操作。

考虑一个包裹--因为这是我的,所以它被巧妙地命名为 mypackage --文件结构如下:宇宙学代码模块和定义相关输入/输出函数的模块。在宇宙学模块中定义了宇宙学类和文件格式-- myformat --而且一切都应该与Astery互操作。测试是用来完成的 pytest 并且被集成在代码结构中。

mypackage/
    __init__.py
    cosmology/
        __init__.py
        ...
    io/
        __init__.py
        astropy_convert.py
        astropy_io.py
        ...
        tests/
            __init__.py
            test_astropy_convert.py
            test_astropy_io.py
            ...

在包之间转换对象#

我们想要实现宇宙学对象之间的转换 mypackage 至/自 Cosmology 。所有Astroy接口代码都在 mypackage/io/astropy_convert.py 。以下是必要函数的粗略概述,以及如何将它们注册到Astopy的统一I/O以供|Cosmology.from_Format|和|Cosmology.To_Format|自动使用。

读写#

中定义了与Astropy读/写相关的所有内容 mypackage/io/astropy_io.py 。以下是读取、写入和标识函数的粗略概述,以及如何将它们注册到Astopy的统一IO以自动用于|Cosmology.Read|和|Cosmology.WRITE|。

如果Astropy是可选的依赖项#

这个 astropy_ioastropy_convert 编写模块的前提是安装了Astropy。如果在 mypackage 这是一个可选的依赖项,因此在导入之前检测是否安装了Astropy(以及正确的版本)非常重要 astropy_ioastropy_convert 。我们在做这件事 mypackage/io/__init__.py

Astroy互操作性测试#

最后,重要的是要测试一切是否正常。在此示例包中,所有此类测试都包含在 mypackage/io/tests/test_astropy_io.py 。这些测试需要Astropy,如果没有安装(并且不是正确的版本),则将被跳过,因此测试矩阵中至少应该包括一个测试 astropy >= 5.0