2

干渉天文データを操作するときに、異なる単位の UV 座標間で変換するための astropy.units の等価性を作成しようとしています。座標を格納する最も一般的な方法は秒単位ですが、通常はラムダに直接変換します (残りの波長/周波数に依存します)。(ナノ) 秒 - (キロ) ラムダ - メートルの間で移動できるようにしたい。変換に必要な入力は、個々の観測の静止周波数です。

メソッドの最初の説明:

これまでに思いついたのは次のとおりです。

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」で配列(オブジェクト属性)を定義します。次に、その場で「ラムダ」または「m」に変換できるようにしたいと考えています。配列クラスを再定義せずにそれを行うことはできますか?

4

1 に答える 1

4

あなたが現在持っているものは機能しますが、実際には少し単純化できます。特に、 astropy.units が変換方法を既に知っている場合、 stoとtoの両方をns定義する必要はありません。さらに単純化するために、 の倍数として定義されていると定義できます。これは与える:msmnsklambdaslambdas

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

その後、波長などを渡すこともできます。

Quantity2 番目の質問については、を継承して単純にオーバーロードする新しい数量クラスを作成する必要があると思いますto

于 2015-01-16T13:47:23.733 に答える