天文单位等效 - 干涉测量基线
Astropy Units equivalencies - interferometry baselines
我正在尝试创建一个 astropy.units 等效项,以便在处理干涉天文数据时在不同的 UV 坐标单位之间进行转换。最常见的坐标存储方式是以秒为单位,但我通常直接转换为 lambda(取决于 rest-wavelength/frequency)。我希望能够介于:(纳)秒 - (千)lambda - 米之间。转换所需的输入是各个观察值的静止频率。
方法初步说明:
到目前为止我想到的是以下内容。
import astropy.units as un
import astropy.constants as co
restfreq_hz = 203e9 #203 Ghz
lambdas = un.def_unit('lambdas', format={'format' : r'\lambda'})
klambdas = un.def_unit('kilolambdas', format={'format' : r'k\lambda'})
# equivalency (from_unit, to_unit, forward, backward)
lambdas_equivalencies = [
(lambdas, un.s, lambda x: x/restfreq_hz, lambda x: x*restfreq_hz),
(lambdas, un.m, lambda x: x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: x/co.c.to(un.m/un.s).value * restfreq_hz),
(lambdas, un.ns, lambda x: x/restfreq_hz * 1e9, lambda x: x / 1e-9*restfreq_hz ),
(lambdas, klambdas, lambda x: x*1e-3, lambda x: x*1e3),
(klambdas, un.s, lambda x: 1e3*x/restfreq_hz, lambda x: 1e-3*x*restfreq_hz),
(klambdas, un.m, lambda x: 1e3*x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: 1e-3*x/co.c.to(un.m/un.s).value * restfreq_hz),
(klambdas, un.ns, lambda x: 1e3*x/restfreq_hz * 1e9, lambda x: 1e-3*x / 1e-9*restfreq_hz ),
(un.m, un.s, lambda x: x/co.c.to(un.m/un.s).value, lambda x: x*co.c.to(un.m/un.s).value),
(un.m, un.ns, lambda x: x/co.c.to(un.m/un.ns).value, lambda x: x*co.c.to(un.m/un.ns).value)
]
举个例子,我现在可以这样做:
In [10]: (100.*klambdas).to(un.m ,equivalencies=lambdas_equivalencies)
Out[10]: <Quantity 147.68101379310343 m>
In [13]: (12 * un.m).to(lambdas, equivalencies=lambdas_equivalencies)
Out[13]: <Quantity 8125.621359026984 lambdas>
In [29]: (1000000*un.ns).to(lambdas, equivalencies=lambdas_equivalencies)
Out[29]: <Quantity 203000000.0 lambdas>
这是 preferred/best 的做法吗,还是我遗漏了什么?欢迎补充 tweaks/tips!
其他问题:
我想把它合并到一个对象中。所以我定义了一个数组(对象属性),单位为 'klambda'。然后我希望能够将其即时转换为 'lambda' 或 'm'。 我可以在不重新定义数组的情况下这样做吗class?
您目前使用的是有效的,但您实际上可以稍微简化它。特别是,如果 astropy.units 已经知道如何转换,例如s
到ns
那么你不需要同时定义m
到s
和m
到ns
,它就能计算出来出来。为了进一步简化,您可以将 klambdas
定义为 lambdas
的倍数。这给出:
lambdas = un.def_unit('lambdas', format={'format' : r'\lambda'})
klambdas = un.def_unit('kilolambdas', 1e3 * lambdas, format={'format' : r'k\lambda'})
# equivalency (from_unit, to_unit, forward, backward)
lambdas_equivalencies = [
(lambdas, un.s, lambda x: x/restfreq_hz, lambda x: x*restfreq_hz),
(lambdas, un.m, lambda x: x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: x/co.c.to(un.m/un.s).value * restfreq_hz),
(un.m, un.s, lambda x: x/co.c.to(un.m/un.s).value, lambda x: x*co.c.to(un.m/un.s).value),
]
实际上,您可能应该有一个函数来计算频率:
def lambdas_equivalencies(restfreq_hz):
eq = [
(lambdas, un.s, lambda x: x/restfreq_hz, lambda x: x*restfreq_hz),
(lambdas, un.m, lambda x: x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: x/co.c.to(un.m/un.s).value * restfreq_hz),
(un.m, un.s, lambda x: x/co.c.to(un.m/un.s).value, lambda x: x*co.c.to(un.m/un.s).value),
]
return eq
然后将其用作
(100.*klambdas).to(un.m ,equivalencies=lambdas_equivalencies(restfreq_hz))
并且您还应该能够让 restfreq_hz 成为一个数量,如果需要,您可以在函数内将其转换为 Hz
::
def lambdas_equivalencies(restfreq):
restfreq_hz = restfreq.to(u.Hz, equivalencies=u.spectral())
...
然后你甚至可以通过波长等
对于你的第二个问题,我认为你可能需要创建一个新的数量 class 继承自 Quantity
并简单地重载 to
.
我正在尝试创建一个 astropy.units 等效项,以便在处理干涉天文数据时在不同的 UV 坐标单位之间进行转换。最常见的坐标存储方式是以秒为单位,但我通常直接转换为 lambda(取决于 rest-wavelength/frequency)。我希望能够介于:(纳)秒 - (千)lambda - 米之间。转换所需的输入是各个观察值的静止频率。
方法初步说明:
到目前为止我想到的是以下内容。
import astropy.units as un
import astropy.constants as co
restfreq_hz = 203e9 #203 Ghz
lambdas = un.def_unit('lambdas', format={'format' : r'\lambda'})
klambdas = un.def_unit('kilolambdas', format={'format' : r'k\lambda'})
# equivalency (from_unit, to_unit, forward, backward)
lambdas_equivalencies = [
(lambdas, un.s, lambda x: x/restfreq_hz, lambda x: x*restfreq_hz),
(lambdas, un.m, lambda x: x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: x/co.c.to(un.m/un.s).value * restfreq_hz),
(lambdas, un.ns, lambda x: x/restfreq_hz * 1e9, lambda x: x / 1e-9*restfreq_hz ),
(lambdas, klambdas, lambda x: x*1e-3, lambda x: x*1e3),
(klambdas, un.s, lambda x: 1e3*x/restfreq_hz, lambda x: 1e-3*x*restfreq_hz),
(klambdas, un.m, lambda x: 1e3*x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: 1e-3*x/co.c.to(un.m/un.s).value * restfreq_hz),
(klambdas, un.ns, lambda x: 1e3*x/restfreq_hz * 1e9, lambda x: 1e-3*x / 1e-9*restfreq_hz ),
(un.m, un.s, lambda x: x/co.c.to(un.m/un.s).value, lambda x: x*co.c.to(un.m/un.s).value),
(un.m, un.ns, lambda x: x/co.c.to(un.m/un.ns).value, lambda x: x*co.c.to(un.m/un.ns).value)
]
举个例子,我现在可以这样做:
In [10]: (100.*klambdas).to(un.m ,equivalencies=lambdas_equivalencies)
Out[10]: <Quantity 147.68101379310343 m>
In [13]: (12 * un.m).to(lambdas, equivalencies=lambdas_equivalencies)
Out[13]: <Quantity 8125.621359026984 lambdas>
In [29]: (1000000*un.ns).to(lambdas, equivalencies=lambdas_equivalencies)
Out[29]: <Quantity 203000000.0 lambdas>
这是 preferred/best 的做法吗,还是我遗漏了什么?欢迎补充 tweaks/tips!
其他问题:
我想把它合并到一个对象中。所以我定义了一个数组(对象属性),单位为 'klambda'。然后我希望能够将其即时转换为 'lambda' 或 'm'。 我可以在不重新定义数组的情况下这样做吗class?
您目前使用的是有效的,但您实际上可以稍微简化它。特别是,如果 astropy.units 已经知道如何转换,例如s
到ns
那么你不需要同时定义m
到s
和m
到ns
,它就能计算出来出来。为了进一步简化,您可以将 klambdas
定义为 lambdas
的倍数。这给出:
lambdas = un.def_unit('lambdas', format={'format' : r'\lambda'})
klambdas = un.def_unit('kilolambdas', 1e3 * lambdas, format={'format' : r'k\lambda'})
# equivalency (from_unit, to_unit, forward, backward)
lambdas_equivalencies = [
(lambdas, un.s, lambda x: x/restfreq_hz, lambda x: x*restfreq_hz),
(lambdas, un.m, lambda x: x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: x/co.c.to(un.m/un.s).value * restfreq_hz),
(un.m, un.s, lambda x: x/co.c.to(un.m/un.s).value, lambda x: x*co.c.to(un.m/un.s).value),
]
实际上,您可能应该有一个函数来计算频率:
def lambdas_equivalencies(restfreq_hz):
eq = [
(lambdas, un.s, lambda x: x/restfreq_hz, lambda x: x*restfreq_hz),
(lambdas, un.m, lambda x: x/restfreq_hz * co.c.to(un.m/un.s).value, lambda x: x/co.c.to(un.m/un.s).value * restfreq_hz),
(un.m, un.s, lambda x: x/co.c.to(un.m/un.s).value, lambda x: x*co.c.to(un.m/un.s).value),
]
return eq
然后将其用作
(100.*klambdas).to(un.m ,equivalencies=lambdas_equivalencies(restfreq_hz))
并且您还应该能够让 restfreq_hz 成为一个数量,如果需要,您可以在函数内将其转换为 Hz
::
def lambdas_equivalencies(restfreq):
restfreq_hz = restfreq.to(u.Hz, equivalencies=u.spectral())
...
然后你甚至可以通过波长等
对于你的第二个问题,我认为你可能需要创建一个新的数量 class 继承自 Quantity
并简单地重载 to
.