等价物#

单位模块具有在特定环境下支持不同单位之间等价性的机制,即当方程可以唯一地将一个单位中的值与另一个单位相关联时。一个很好的例子是波长、频率和能量之间的等价性,用于指定辐射的波长。通常这些单位是不可转换的,但当理解为代表光时,它们在某些情况下是可转换的。这里我们描述如何使用 astropy.units 以及如何定义新的等价物。

通过将等价对的列表传递给 equivalencies 的关键字参数 Quantity.to() Unit.to()Unit.get_converter() 方法:研究方法。该列表可以直接提供,但是 astropy 包含几个返回适当列表的函数,因此通常不需要构造它们。或者,如果较大的代码片段需要相同的等效项,则可以将它们设置为 given context

内置等价物#

如何将视差转换为距离#

长度单位 parsec 是这样定义的,即距离恒星一秒的恒星将呈现1角秒的视差。(把这个名字想象成一个缩写 parallaxarcsecond 。)

这个 parallax() 函数处理视差角度和长度之间的转换。

一般来说,不应该将长度单位转换为角度,反之亦然,因此 to() 引发异常:

>>> from astropy import units as u
>>> (0.8 * u.arcsec).to(u.parsec)  
Traceback (most recent call last):
  ...
UnitConversionError: 'arcsec' (angle) and 'pc' (length) are not convertible

要触发视差角和距离之间的转换,请提供 parallax() 作为可选关键字参数 (equivalencies=to() 方法。

>>> (0.8 * u.arcsec).to(u.parsec, equivalencies=u.parallax())
<Quantity 1.25 pc>

以无量纲单位表示的角度#

角度被视为物理上不同的类型,这通常有助于避免错误。但是,当使用与旋转能量或小角度近似相关的单位时,这并不是很方便。(事实上,这种双面性是为什么弧度从一个 supplementary to derived unit 。)该功能 dimensionless_angles() 提供有助于在角度和无量纲单位之间进行转换的所需等效项列表。它与所有其他弧度的不同之处在于,它允许任意改变弧度的幂的数量(即,包括零,因此是无量纲的)。

实例#

通常,以下情况会引发异常:

>>> u.degree.to('')  
Traceback (most recent call last):
  ...
UnitConversionError: 'deg' (angle) and '' (dimensionless) are not convertible
>>> (u.kg * u.m**2 * (u.cycle / u.s)**2).to(u.J)  
Traceback (most recent call last):
  ...
UnitConversionError: 'cycle2 kg m2 / s2' and 'J' (energy) are not convertible

但当传递正确的转换函数时, dimensionless_angles() ,它起作用了。

>>> u.deg.to('', equivalencies=u.dimensionless_angles())  
0.017453292519943295
>>> (0.5e38 * u.kg * u.m**2 * (u.cycle / u.s)**2).to(u.J,
...                            equivalencies=u.dimensionless_angles())  
<Quantity 1.9739208802178715e+39 J>
>>> import numpy as np
>>> np.exp((1j*0.125*u.cycle).to('', equivalencies=u.dimensionless_angles())) 
<Quantity  0.70710678+0.70710678j>

在一个复数的例子中,你可能正在做大量类似的计算。对于这种情况,可以选择 set default equivalencies .

在某些情况下,这种等效性可能表现出与预期不同的行为。例如,一开始用它来转换角速度似乎是合理的 \(\omega\) 以弧度/秒表示 \(f\) 以赫兹为单位(即 \(f=\omega/2\pi\) ). 但是,尝试这样做会产生:

>>> (1*u.rad/u.s).to(u.Hz, equivalencies=u.dimensionless_angles())  
<Quantity 1. Hz>
>>> (1*u.cycle/u.s).to(u.Hz, equivalencies=u.dimensionless_angles())  
<Quantity 6.283185307179586 Hz>

在这里,我们在第一个例子中可能预期为0.159赫兹,在第二个例子中是1赫兹。然而, dimensionless_angles() 转换为每秒弧度,然后将弧度作为单位降低。在这些例子中犯的一个隐含的错误是,单位Hz被视为等于每秒的周期数,而不是(它只是“每秒”)。这一实现也带来了解决方案:在每秒循环次数和赫兹之间使用显式等效:

>>> (1*u.rad/u.s).to(u.Hz, equivalencies=[(u.cy/u.s, u.Hz)])  
<Quantity 0.15915494309189535 Hz>
>>> (1*u.cy/u.s).to(u.Hz, equivalencies=[(u.cy/u.s, u.Hz)])  
<Quantity 1. Hz>

光谱单位#

spectral() 是一个函数,它返回一个等价列表来处理波长、频率、能量和波数之间的转换。

正如在视差单位中提到的,我们传递一个等价列表(在本例中,结果是 spectral() )作为 to() 方法和波长,然后频率和能量可以转换。

>>> ([1000, 2000] * u.nm).to(u.Hz, equivalencies=u.spectral())  
<Quantity [2.99792458e+14, 1.49896229e+14] Hz>
>>> ([1000, 2000] * u.nm).to(u.eV, equivalencies=u.spectral())  
<Quantity [1.23984193, 0.61992096] eV>

这些等价物甚至适用于非基本单位:

>>> # Inches to calories
>>> from astropy.units import imperial
>>> imperial.inch.to(imperial.Cal, equivalencies=u.spectral())  
1.869180759162485e-27

光谱(多普勒)当量#

光谱等效允许你在波长、频率、能量和波数之间进行转换,但不能转换为速度,而速度通常是感兴趣的量。

定义等价性是相当方便的,但是要注意的是有不同的 conventions . 在这些公约中 \(f_0\) 是静止频率, \(f\) 是观察到的频率, \(V\) 是速度,和 \(c\) 是光速:

  • 无线电 \(V = c \frac{{f_0 - f}}{{f_0}} ; f(V) = f_0 ( 1 - V/c )\)

  • 光学的 \(V = c \frac{{f_0 - f}}{{f }} ; f(V) = f_0 ( 1 + V/c )^{{-1}}\)

  • 相对论的 \(V = c \frac{{f_0^2 - f^2}}{{f_0^2 + f^2}} ; f(V) = f_0 \frac{{\left(1 - (V/c)^2\right)^{{1/2}}}}{{(1+V/c)}}\)

这三个公约在 astropy.units.equivalencies 作为 doppler_optical()doppler_radio()doppler_relativistic() .

例子#

定义等价性:

>>> restfreq = 115.27120 * u.GHz  # rest frequency of 12 CO 1-0 in GHz
>>> freq_to_vel = u.doppler_radio(restfreq)
>>> (116e9 * u.Hz).to(u.km / u.s, equivalencies=freq_to_vel)  
<Quantity -1895.4321928669085 km / s>

光谱通量和光度密度单位#

还支持光谱通量和光度密度单位、它们的等效表面亮度单位和积分通量单位。它们的使用更为复杂,因为还需要提供光谱中要进行转换的位置以及这些光谱位置的单位。处理这些单位转换的函数是 spectral_density() . 此函数将 Quantity 对于光谱定位。

例子#

执行单位转换 spectral_density() ::

>>> (1.5 * u.Jy).to(u.photon / u.cm**2 / u.s / u.Hz,
...                 equivalencies=u.spectral_density(3500 * u.AA)) 
<Quantity 2.6429112e-12 ph / (Hz s cm2)>
>>> (1.5 * u.Jy).to(u.photon / u.cm**2 / u.s / u.micron,
...                 equivalencies=u.spectral_density(3500 * u.AA))  
<Quantity 6467.95791275 ph / (micron s cm2)>
>>> a = 1. * (u.photon / u.s / u.angstrom)
>>> a.to(u.erg / u.s / u.Hz,
...      equivalencies=u.spectral_density(5500 * u.AA))  
<Quantity 3.6443382634999996e-23 erg / (Hz s)>
>>> w = 5000 * u.AA
>>> a = 1. * (u.erg / u.cm**2 / u.s)
>>> b = a.to(u.photon / u.cm**2 / u.s, u.spectral_density(w))
>>> b  
<Quantity 2.51705828e+11 ph / (s cm2)>
>>> b.to(a.unit, u.spectral_density(w))  
<Quantity 1. erg / (s cm2)>

亮度温度和表面亮度当量#

表面亮度(单位面积的通量密度)和亮度温度之间是等价的。这种等效性通常被称为“天线增益”,因为在给定频率下,望远镜的亮度灵敏度与孔径大小无关,而通量密度灵敏度则与孔径大小无关,因此这种等效性仅取决于孔径大小。看到了吗 Tools of Radio Astronomy 有关详细信息。

备注

这里提到的亮度温度是Rayleigh-Jeans等效温度,这使得通量和温度成线性关系。这是最常用于观察的约定,但是如果您对计算 准确的 黑体函数的温度,会产生一个给定的通量,你不应该使用这个等价物。

实例#

这个 brightness_temperature() 等价性要求以波束面积和频率作为自变量。回想一下二维高斯的面积是 \(2 \pi \sigma^2\) (见 wikipedia ),下面是一个例子:

>>> beam_sigma = 50*u.arcsec
>>> omega_B = 2 * np.pi * beam_sigma**2
>>> freq = 5 * u.GHz
>>> (1*u.Jy/omega_B).to(u.K, equivalencies=u.brightness_temperature(freq))  
<Quantity 3.526295144567176 K>

如果有波束全宽半最大值(FWHM),它经常被引用,并且是存储在FITS标题关键字BMAJ和BMIN中的值,则一个更合适的示例将FWHM转换为sigma::

>>> beam_fwhm = 50*u.arcsec
>>> fwhm_to_sigma = 1. / (8 * np.log(2))**0.5
>>> beam_sigma = beam_fwhm * fwhm_to_sigma
>>> omega_B = 2 * np.pi * beam_sigma**2
>>> (1*u.Jy/omega_B).to(u.K, equivalencies=u.brightness_temperature(freq))  
<Quantity 19.553932298231704 K>

您也可以在 Jy/beamK 通过指定梁面积:

>>> (1*u.Jy/u.beam).to(u.K, u.brightness_temperature(freq, beam_area=omega_B))  
<Quantity 19.553932298231704 K>

光束等效性#

无线电数据,特别是来自干涉仪的数据,通常以 Jy/beam 。将该数字转换为与波束无关的值(例如, Jy/sr ),可以使用 beam_angular_area() 等价性。

例子#

换算单位 Jy/beamJy/sr ::

>>> beam_fwhm = 50*u.arcsec
>>> fwhm_to_sigma = 1. / (8 * np.log(2))**0.5
>>> beam_sigma = beam_fwhm * fwhm_to_sigma
>>> omega_B = 2 * np.pi * beam_sigma**2
>>> (1*u.Jy/u.beam).to(u.MJy/u.sr, equivalencies=u.beam_angular_area(omega_B))  
<Quantity 15.019166691021288 MJy / sr>

请注意 radio_beam 该软件包更直接地处理光束输入/输出和各种操作。

温度能量当量#

这个 temperature_energy() 当量允许在温度和其能量当量(即温度乘以玻尔兹曼常数)之间进行转换,通常以电子伏特表示。它经常用于高能观测,无论是太阳天文学还是X射线天文学。

例子#

在温度和它的等效能量之间转换:

>>> t_k = 1e6 * u.K
>>> t_k.to(u.eV, equivalencies=u.temperature_energy())  
<Quantity 86.17332384960955 eV>

热力学温度当量#

这个 thermodynamic_temperature() 等价性允许在 Jy/beam 和“热力学温度”, \(T_{{CMB}}\) ,在凯尔文。

实例#

在…之间转换 Jy/beam 热力学温度:

>>> nu = 143 * u.GHz
>>> t_k = 0.002632051878 * u.K
>>> t_k.to(u.MJy / u.sr, equivalencies=u.thermodynamic_temperature(nu))  
<Quantity 1. MJy / sr>

默认情况下,这将使用 \(T_{CMB}\) 默认值的值 cosmology 在……里面 astropy ,但也可以指定自定义 \(T_{CMB}\) 作为等价性的第二个自变量的特定宇宙学的值:

>>> from astropy.cosmology import WMAP9
>>> t_k.to(u.MJy / u.sr, equivalencies=u.thermodynamic_temperature(nu, T_cmb=WMAP9.Tcmb0))  
<Quantity 0.99982392 MJy / sr>

摩尔质量AMU当量#

这个 molar_mass_amu() 当量允许原子质量单位和当量克/摩尔之间的换算。有关上下文,请参阅 NIST definition of SI Base Units

例子#

在原子质量单位和当量g/mol之间转换:

>>> x = 1 * (u.g / u.mol)
>>> y = 1 * u.u
>>> x.to(u.u, equivalencies=u.molar_mass_amu()) 
<Quantity 1.0 u>
>>> y.to(u.g/u.mol, equivalencies=u.molar_mass_amu()) 
<Quantity 1.0 g / mol>

像素和板比例等效#

这些等价物用于在角度标度和焦平面中的线性标度或以像素数为单位的距离之间进行转换。

实例#

假设您正在使用Sloan Digital Sky Survey中的剪贴画,默认像素比例为每像素0.4弧秒,并且希望知道在剪切图像中测量到的东西的真实大小为240像素:

>>> sdss_pixelscale = u.pixel_scale(0.4*u.arcsec/u.pixel)
>>> (240*u.pixel).to(u.arcmin, sdss_pixelscale)  
<Quantity 1.6 arcmin>

或者,你正在为一台望远镜设计一台仪器,有人告诉你,它的反转刻度为每弧度7.8米(为了你想要的焦距),你想知道你的像素需要多大才能覆盖半角秒。vbl.使用 plate_scale() **

>>> tel_platescale = u.plate_scale(7.8*u.m/u.radian)
>>> (0.5*u.arcsec).to(u.micron, tel_platescale)  
<Quantity 18.9077335632719 micron>

这个 pixel_scale() 等价性也可以在更一般的情况下工作,在这种情况下,比例被指定为可简化为的任何量 <composite unit>/u.pixu.pix/<composite unit> (即,数据的维度 u.pix 为1或-1)。例如,您可以定义数字图像的每英寸点数(DPI)来计算其物理大小:

>>> dpi = u.pixel_scale(100 * u.pix / u.imperial.inch)
>>> (1024 * u.pix).to(u.cm, dpi)  
<Quantity 26.0096 cm>

光度零点当量#

这个 zero_point_flux() 等效性提供了一种在光度学系统(即相对于特定零点通量定义的系统)和绝对通量之间移动的方法。这与支持 震级和其他对数单位

例子#

假设您正在观察一个带有过滤器的目标,报告的标准零点为3631.1 Jy::

>>> target_flux = 1.2 * u.nanomaggy
>>> zero_point_star_equiv = u.zero_point_flux(3631.1 * u.Jy)
>>> u.Magnitude(target_flux.to(u.AB, zero_point_star_equiv))  
<Magnitude 22.30195136 mag(AB)>

温度当量#

这个 temperature() 当量允许在摄氏度、华氏度、兰金和开尔文之间进行转换。

例子#

在温标之间转换:

>>> temp_C = 0 * u.Celsius
>>> temp_Kelvin = temp_C.to(u.K, equivalencies=u.temperature())
>>> temp_Kelvin  
<Quantity 273.15 K>
>>> temp_F = temp_C.to(u.imperial.deg_F, equivalencies=u.temperature())
>>> temp_F  
<Quantity 32. deg_F>
>>> temp_R = temp_C.to(u.imperial.deg_R, equivalencies=u.temperature())
>>> temp_R  
<Quantity 491.67 deg_R>

备注

您也可以使用 u.deg_C 而不是 u.Celsius .

质能当量#

在狭义相对论上下文中,使用 mass_energy() 等价性。例如:

>>> (1 * u.g).to(u.eV, u.mass_energy())  
<Quantity 5.60958865e+32 eV>

多普勒红移等效性#

多普勒红移和径向速度之间的转换可以使用 doppler_redshift() 等价性。

例子#

要将多普勒红移(无单位)转换为 km/s **

>>> z = 0.1 * u.dimensionless_unscaled
>>> z.to(u.km / u.s, u.doppler_redshift())  
<Quantity 28487.0661448 km / s>

然而,它不能将宇宙红移单位从 astropy.cosmology.units because the latter should not be interpreted the same since the recessional velocity from the expansion of space can exceed the speed of light; see Hubble's law: Redshift velocity and recessional velocity 以获取更多信息。

编写新的等价物#

等效列表是一个 list 元组,其中每个元组 tuple 有四个要素:

(from_unit, to_unit, forward, backward)

from_unitto_unit 是等价的单位。 forwardbackward 是在这些单位之间转换值的函数。 forwardbackward 是可选的,如果省略,则等价性声明这两个单位应被视为相等。函数必须接受并返回非 Quantity 对象以避免无限递归;请参见 一个更复杂的例子:频谱多普勒等效 了解更多详细信息。

实例#

直到1964年,公升的定义是在4°C、760毫米汞柱压力下1kg水的体积。体积和质量通常不能直接转换,但如果我们把1964年对升的定义中的常数保持为真,我们就可以为它们建立一个等价关系:

>>> liters_water = [
...    (u.l, u.g, lambda x: 1000.0 * x, lambda x: x / 1000.0)
... ]
>>> u.l.to(u.kg, 1, equivalencies=liters_water)
1.0

请注意,等效性可用于任何其他兼容单元:

>>> imperial.gallon.to(imperial.pound, 1, equivalencies=liters_water)  
8.345404463333525

它也在另一个方向起作用:

>>> imperial.lb.to(imperial.pint, 1, equivalencies=liters_water)  
0.9586114172355459

一个更复杂的例子:频谱多普勒等效#

我们将展示如何使用CO 1-0的无线电约定来定义等效性。此函数已在中定义 doppler_radio() ,但这个例子是说明性的:

>>> from astropy.constants import si
>>> restfreq = 115.27120  # rest frequency of 12 CO 1-0 in GHz
>>> freq_to_vel = [(u.GHz, u.km/u.s,
... lambda x: (restfreq-x) / restfreq * si.c.to_value('km/s'),
... lambda x: (1-x/si.c.to_value('km/s')) * restfreq )]
>>> u.Hz.to(u.km / u.s, 116e9, equivalencies=freq_to_vel)  
-1895.4321928669262
>>> (116e9 * u.Hz).to(u.km / u.s, equivalencies=freq_to_vel)  
<Quantity -1895.4321928669262 km / s>

请注意,一旦为GHz和KM/S定义了这一点,它将适用于所有其他频率和速度单位。 x 从输入频率单位(例如,赫兹)转换到GHz,然后传递到 lambda x: 。同样,假定返回值的单位为 km/s ,这就是为什么 valuec 是用来代替 Constant

显示可用的等效项#

这个 find_equivalent_units() 方法也理解等价性。

例子#

在不传递等价物的情况下,有三个兼容的单元 Hz 在标准集中:

>>> u.Hz.find_equivalent_units()
  Primary name | Unit definition | Aliases
[
  Bq           | 1 / s           | becquerel    ,
  Ci           | 3.7e+10 / s    | curie        ,
  Hz           | 1 / s           | Hertz, hertz ,
]

然而,当通过光谱等效性时,你可以看到有各种各样的东西 Hz 可以转换为:

>>> u.Hz.find_equivalent_units(equivalencies=u.spectral())
Primary name | Unit definition        | Aliases
[
  AU           | 1.49598e+11 m          | au, astronomical_unit            ,
  Angstrom     | 1e-10 m                | AA, angstrom                     ,
  Bq           | 1 / s                  | becquerel                        ,
  Ci           | 3.7e+10 / s            | curie                            ,
  Hz           | 1 / s                  | Hertz, hertz                     ,
  J            | m2 kg / s2             | Joule, joule                     ,
  Ry           | 2.17987e-18 m2 kg / s2 | rydberg                          ,
  cm           | 0.01 m                 | centimeter                       ,
  eV           | 1.60218e-19 m2 kg / s2 | electronvolt                     ,
  earthRad     | 6.3781e+06 m           | R_earth, Rearth                  ,
  erg          | 1e-07 m2 kg / s2       |                                  ,
  jupiterRad   | 7.1492e+07 m           | R_jup, Rjup, R_jupiter, Rjupiter ,
  k            | 100 / m                | Kayser, kayser                   ,
  lsec         | 2.99792e+08 m          | lightsecond                      ,
  lyr          | 9.46073e+15 m          | lightyear                        ,
  m            | irreducible            | meter                            ,
  micron       | 1e-06 m                |                                  ,
  pc           | 3.08568e+16 m          | parsec                           ,
  solRad       | 6.957e+08 m            | R_sun, Rsun                      ,
]

使用较大的代码段#

有时,你可能会有一个复杂的计算,你经常在相等的单位之间来回切换。对于这些情况,您可以设置默认情况下将使用的等价性,方法类似于您可以使用的方式 enable other units .

实例#

要使弧度被视为无因次单位,请使用 set_enabled_equivalencies() 作为一名 context manager **

>>> with u.set_enabled_equivalencies(u.dimensionless_angles()):
...    phase = 0.5 * u.cycle
...    c = np.exp(1j*phase)
>>> c  
<Quantity -1.+1.2246468e-16j>

永久和全局启用弧度作为无量纲单位使用 set_enabled_equivalencies() 不是作为环境管理者:

>>> u.set_enabled_equivalencies(u.dimensionless_angles())
<astropy.units.core._UnitContext object at ...>
>>> u.deg.to('')  
0.017453292519943295

上述方法的缺点是您可能忘记关闭默认设置(通过给出一个空参数来完成)。

set_enabled_equivalencies() 接受任何等效项列表,因此您可以添加,例如, spectral()spectral_density() (因为这些返回列表确实应该通过将它们相加来组合在一起)。