2015-01-16 25 views
1

我正在嘗試創建一個astropy.units等效函數,以便在使用干涉天文數據進行處理時在不同的UV座標單位之間進行轉換。存儲座標的最常見方式是以秒爲單位,但我通常直接轉換爲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> 

這是這樣做的最佳/最好的辦法,還是我失去了一些東西的任何額外的微調/提示是歡迎!

增發(S):

我想將其納入一個對象這一點。這樣我就可以定義一個數組(對象屬性),用單位「klambda」來表示。然後,我希望能夠將其即時轉換爲「lambda」或「m」。 我可以在不重新定義數組類的情況下做到這一點嗎?

回答

2

你目前的工作,但你實際上可以簡化一點。特別是,如果astropy.units已經知道如何轉換例如sns那麼你不需要同時定義msmns,它將能夠找出它。爲了進一步簡化,您可以將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()) 
    ... 

,那麼你甚至可以通過波長等

關於第二個問題,我想你可能要創建一個從Quantity繼承一個新的數量級,只是重載to

+0

不錯,謝謝!它只是讓事情變得更好,能夠添加單位的東西。也許對別人有幫助。 –

+0

對於我的第二個問題,我最終通過全局定義'lambdas_equivalencies'來解決問題,並且在我希望數量爲對象的對象中,我首先定義了'u.add_enabled_equivalencies(lambdas_equivalencies(restfreq_unit))'restfreq_unit' value是每個對象的個體。經過一些測試後,似乎'u.add_enabled_equivalencies'只在本地定義了等同性,即我可以用不同的restfreq_unit創建幾個對象,並且每個對象的轉換都保持正確。 –

+0

'klambdas = un.def_unit('kilolambdas',1e3 * lambdas,format = {'format':r'k \ lambda'})'他們是不是也定義'lambdas'來接受SI前綴?也許矯枉過正,但它不會與我能想到的其他任何東西重疊。 – Iguananaut