python - 天体单位等效 - 干涉测量基线

标签 python astronomy astropy

我正在尝试创建一个 astropy.units 等效项,以便在处理干涉天文数据时在不同的 UV 坐标单位之间进行转换。存储坐标的最常见方法是以秒为单位,但我通常直接转换为 lambda(取决于剩余波长/频率)。我希望能够在:(纳)秒 - (千) 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>

这是执行此操作的首选/最佳方式,还是我遗漏了某些内容?欢迎任何其他调整/提示!

其他问题:

我想将其合并到一个对象中。这样我就可以用单位“klambda”定义一个数组(对象属性)。然后我希望能够将其即时转换为“lambda”或“m”。 我可以在不重新定义数组类的情况下做到这一点吗?

最佳答案

您当前所拥有的内容可以工作,但实际上您可以稍微简化一下。特别是,如果 astropy.units 已经知道如何转换,例如sns 那么你不需要同时定义 msm 改为 ns,它就能算出来。为了进一步简化,您可以将 klambdas 定义为 lambda 的倍数。这给出:

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())
    ...

那么你甚至可以传递波长等。

对于第二个问题,我认为您可能必须创建一个新的数量类,该类继承自 Quantity 并简单地重载 to

关于python - 天体单位等效 - 干涉测量基线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27981489/

相关文章:

python - PostParameters 列表(Python 请求)

ruby - 在 Ruby 中计算天文事件的最可靠方法是什么?

python - pyEphem的RA/Dec和Alt/Azi转换困难

python - 在特定索引处将 numpy 数组的元素增加 1(用于对 astropy 表进行分组)

python - 在 astropy.modeling 中绑定(bind)参数

javascript - 哪种编程语言可以同时从网络上抓取数据并进行 api 调用?

Python:计算从一个目录到另一个目录的相对路径

python - Astroscrappy 无法在多处理 Jupyter 上工作

javascript - 使用 selenium 检查 javascript 异常?

python curve_fit 没有给出合理的拟合结果