开发人员的宇宙学#
函数中的宇宙论#
假设一个默认的宇宙学通常是有用的,这样就不必在每次调用函数或方法时都指定确切的宇宙学。在这种情况下,可以指定一个“默认的”宇宙学。
中的“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_scalar
和 self._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_io
和 astropy_convert
编写模块的前提是安装了Astropy。如果在 mypackage
这是一个可选的依赖项,因此在导入之前检测是否安装了Astropy(以及正确的版本)非常重要 astropy_io
和 astropy_convert
。我们在做这件事 mypackage/io/__init__.py
:
Astroy互操作性测试#
最后,重要的是要测试一切是否正常。在此示例包中,所有此类测试都包含在 mypackage/io/tests/test_astropy_io.py
。这些测试需要Astropy,如果没有安装(并且不是正确的版本),则将被跳过,因此测试矩阵中至少应该包括一个测试 astropy >= 5.0
。