NDDataアルゴリズム

序言:序言

NDDataRef 以下の算術演算を実現する。

基本的な算数方法を使う

標準算術方法を使用して要求される第1のオペランドは NDDataRef 例:

>>> from astropy.nddata import NDDataRef
>>> from astropy.wcs import WCS
>>> import numpy as np
>>> ndd1 = NDDataRef([1, 2, 3, 4])

一方,第2オペランドに対する要求は,第1オペランドに変換可能でなければならないことである.これは数字でもあります

>>> ndd1.add(3)
NDDataRef([4, 5, 6, 7])

あるいは…。 list **

>>> ndd1.subtract([1,1,1,1])
NDDataRef([0, 1, 2, 3])

あるいは…。 numpy.ndarray **

>>> ndd1.multiply(np.arange(4, 8))
NDDataRef([ 4, 10, 18, 28])
>>> ndd1.divide(np.arange(1,13).reshape(3,4))  # a 3 x 4 numpy array  
NDDataRef([[1.        , 1.        , 1.        , 1.        ],
           [0.2       , 0.33333333, 0.42857143, 0.5       ],
           [0.11111111, 0.2       , 0.27272727, 0.33333333]])

ここで,ブロードキャストは異なる次元を扱う.他のいくつかの種類も可能だ。

算数類使用術

ここで,2つのオペランドはすべてである必要はない. NDDataRef -好き::

>>> NDDataRef.add(1, 3)
NDDataRef(4)

2つの量間で算術演算を改行するためには、以下の動作を実行してください。

>>> import astropy.units as u
>>> ndd = NDDataRef.multiply([1,2] * u.m, [10, 20] * u.cm)
>>> ndd  
NDDataRef([10., 40.])
>>> ndd.unit
Unit("cm m")

あるいはそれとは逆のものを取ります NDDataRef 対象::

>>> NDDataRef.divide(1, ndd1)  
NDDataRef([1.        , 0.5       , 0.33333333, 0.25      ])

可能オペランド

オペランドの可能な入力タイプは,

  • どんな種類のスカラーでも

  • 数字を含むリスト(または入れ子リスト)

  • numpy アレイ.アレイ

  • numpy シールドアレイ.

  • astropy

  • 他にも nddata 類または子類

高度なオプション

The normal Python operators +, -, etc. are not implemented because the methods provide several options on how to proceed with the additional attributes.

データと単位

上の data そして unit パラメータがありません。すべての算術演算は astropy.units.Quantity -フレームワーク評価結果または失敗し、動作を中止します。

2つ追加する NDData 同じ単位を持つオブジェクト動作:

>>> ndd1 = NDDataRef([1,2,3,4,5], unit='m')
>>> ndd2 = NDDataRef([100,150,200,50,500], unit='m')

>>> ndd = ndd1.add(ndd2)
>>> ndd.data  
array([101., 152., 203.,  54., 505.])
>>> ndd.unit
Unit("m")

2つ追加する NDData 互換単位を持つオブジェクトは、以下のようにしてもよい。

>>> ndd1 = NDDataRef(ndd1, unit='pc')
INFO: overwriting NDData's current unit with specified unit. [astropy.nddata.nddata]
>>> ndd2 = NDDataRef(ndd2, unit='lyr')
INFO: overwriting NDData's current unit with specified unit. [astropy.nddata.nddata]

>>> ndd = ndd1.subtract(ndd2)
>>> ndd.data  
array([ -29.66013938,  -43.99020907,  -58.32027876,  -11.33006969,
       -148.30069689])
>>> ndd.unit
Unit("pc")

デフォルトの場合、これは第1の操作オブジェクトの単位を保持する。しかし,単位は分割過程で分解されない:

>>> ndd = ndd2.divide(ndd1)
>>> ndd.data  
array([100.        ,  75.        ,  66.66666667,  12.5       , 100.        ])
>>> ndd.unit
Unit("lyr / pc")

日除け.

♪the handle_mask 算術演算のためのパラメータ実装結果マスクは何であるか。いくつかの選択肢があります。

  • None 結果はありません mask **

    >>> ndd1 = NDDataRef(1, mask=True)
    >>> ndd2 = NDDataRef(1, mask=False)
    >>> ndd1.add(ndd2, handle_mask=None).mask is None
    True
    
  • "first_found" あるいは…。 "ff" 結果的には mask 最初のオペランドの値、またはそうであれば None vt.的 mask 第2のオペランド:

    >>> ndd1 = NDDataRef(1, mask=True)
    >>> ndd2 = NDDataRef(1, mask=False)
    >>> ndd1.add(ndd2, handle_mask="first_found").mask
    True
    >>> ndd3 = NDDataRef(1)
    >>> ndd3.add(ndd2, handle_mask="first_found").mask
    False
    
  • 少なくとも2つのパラメータを受け入れる関数(または任意の呼び出し可能な関数)。例えば numpy.logical_or デフォルト設定です:

    >>> ndd1 = NDDataRef(1, mask=np.array([True, False, True, False]))
    >>> ndd2 = NDDataRef(1, mask=np.array([True, False, False, True]))
    >>> ndd1.add(ndd2).mask
    array([ True, False,  True,  True]...)
    

    このデフォルト値は "first_found" もし一つだけなら mask 無ではない。

    >>> ndd1 = NDDataRef(1)
    >>> ndd2 = NDDataRef(1, mask=np.array([True, False, False, True]))
    >>> ndd1.add(ndd2).mask
    array([ True, False, False,  True]...)
    

    カスタム関数も可能です:

    >>> def take_alternating_values(mask1, mask2, start=0):
    ...     result = np.zeros(mask1.shape, dtype=np.bool_)
    ...     result[start::2] = mask1[start::2]
    ...     result[start+1::2] = mask2[start+1::2]
    ...     return result
    

    この関数はでたらめですがどのように実行されているのかを見ることができます

    >>> ndd1 = NDDataRef(1, mask=np.array([True, False, True, False]))
    >>> ndd2 = NDDataRef(1, mask=np.array([True, False, False, True]))
    >>> ndd1.add(ndd2, handle_mask=take_alternating_values).mask
    array([ True, False,  True,  True]...)
    

    パラメータの前にプレフィックスを加えることで他のパラメータを与えることができる. mask_ (関数に渡す前に剥離される):

    >>> ndd1.add(ndd2, handle_mask=take_alternating_values, mask_start=1).mask
    array([False, False, False, False]...)
    >>> ndd1.add(ndd2, handle_mask=take_alternating_values, mask_start=2).mask
    array([False, False,  True,  True]...)
    

メタ.

♪the handle_meta パラメータ実現の算術演算の結果は何ですか meta きっとそうします。これらの選択肢は mask

  • もし None ここから生まれたのは meta 空になるでしょう collections.OrderedDict それがそうです。

    >>> ndd1 = NDDataRef(1, meta={'object': 'sun'})
    >>> ndd2 = NDDataRef(1, meta={'object': 'moon'})
    >>> ndd1.add(ndd2, handle_meta=None).meta
    OrderedDict()
    

    上の meta これはデフォルト設定なので、本例ではそれを渡す必要はありません:

    >>> ndd1.add(ndd2).meta
    OrderedDict()
    
  • もし "first_found" あるいは…。 "ff" このようにして生まれたのは meta そうなるだろう meta 第1のオペランドがキーを含まない場合、またはそのオペランドがキーを含まない場合、 meta 2つ目の操作対象の。

    >>> ndd1 = NDDataRef(1, meta={'object': 'sun'})
    >>> ndd2 = NDDataRef(1, meta={'object': 'moon'})
    >>> ndd1.add(ndd2, handle_meta='ff').meta
    {'object': 'sun'}
    
  • もしそれが1つなら callable それは少なくとも二つの論争が必要でなければならない。どちらもある meta 属性はこの関数に渡され(いずれか一方または両方が空であっても),関数が計算結果を呼び出すことができる. meta それがそうです。例えば、以下の2項の関数をマージする:

    >>> # It's expected with arithmetics that the result is not a reference,
    >>> # so we need to copy
    >>> from copy import deepcopy
    
    >>> def combine_meta(meta1, meta2):
    ...     if not meta1:
    ...         return deepcopy(meta2)
    ...     elif not meta2:
    ...         return deepcopy(meta1)
    ...     else:
    ...         meta_final = deepcopy(meta1)
    ...         meta_final.update(meta2)
    ...         return meta_final
    
    >>> ndd1 = NDDataRef(1, meta={'time': 'today'})
    >>> ndd2 = NDDataRef(1, meta={'object': 'moon'})
    >>> ndd1.subtract(ndd2, handle_meta=combine_meta).meta 
    {'object': 'moon', 'time': 'today'}
    

    ここで,関数の付加的なパラメータはプレフィックス入力を用いてもよい. meta_ (これは、この関数に渡す前に剥離される)。詳細については、マスク属性の説明を参照されたい。

世界座標系(WCS)

♪the compare_wcs パラメータは結果を決定します wcs その操作が禁止されるべきか、または禁止されるべきかどうか。可能な値と mask そして meta

  • もし None ここから生まれたのは wcs 空になるでしょう None それがそうです。

    >>> ndd1 = NDDataRef(1, wcs=None)
    >>> ndd2 = NDDataRef(1, wcs=WCS())
    >>> ndd1.add(ndd2, compare_wcs=None).wcs is None
    True
    
  • もし "first_found" あるいは…。 "ff" ここから生まれたのは wcs そうなるだろう wcs 最初のオペランドの値、またはそうであれば None vt.的 meta 2つ目の操作対象の。

    >>> wcs = WCS()
    >>> ndd1 = NDDataRef(1, wcs=wcs)
    >>> ndd2 = NDDataRef(1, wcs=None)
    >>> str(ndd1.add(ndd2, compare_wcs='ff').wcs) == str(wcs)
    True
    
  • もしそれが1つなら callable それは少なくとも二つの論争が必要でなければならない。どちらもある wcs 属性はこの関数に渡されます(いずれか一方または両方であっても None )であれば、呼び出しオブジェクトは返さなければなりません。 True もしこれが wcs 算術演算を可能にするために同じ(十分) False 算術演算を使うべきなら ValueError それがそうです。もし True ♪the wcs 同じです最初のものは結果です

    >>> def compare_wcs_scalar(wcs1, wcs2, allowed_deviation=0.1):
    ...     if wcs1 is None and wcs2 is None:
    ...         return True  # both have no WCS so they are identical
    ...     if wcs1 is None or wcs2 is None:
    ...         return False  # one has WCS, the other doesn't not possible
    ...     else:
    ...         # Consider wcs close if centers are close enough
    ...         return all(abs(wcs1.wcs.crpix - wcs2.wcs.crpix) < allowed_deviation)
    
    >>> ndd1 = NDDataRef(1, wcs=None)
    >>> ndd2 = NDDataRef(1, wcs=None)
    >>> ndd1.subtract(ndd2, compare_wcs=compare_wcs_scalar).wcs
    

    付加的なパラメータは,それらの前に接頭辞を付加して渡すことができる wcs_ (プレフィックスは関数に渡す前に剥離される):

    >>> ndd1 = NDDataRef(1, wcs=WCS())
    >>> ndd1.wcs.wcs.crpix = [1, 1]
    >>> ndd2 = NDDataRef(1, wcs=WCS())
    >>> ndd1.subtract(ndd2, compare_wcs=compare_wcs_scalar, wcs_allowed_deviation=2).wcs.wcs.crpix
    array([1., 1.])
    

    もしあなたが使っているのは WCS オブジェクトの場合、使用可能な非常に便利な関数は、以下のようになるかもしれない。

    >>> def wcs_compare(wcs1, wcs2, *args, **kwargs):
    ...     return wcs1.wcs.compare(wcs2.wcs, *args, **kwargs)
    

    astropy.wcs.Wcsprm.compare() これに対して許容されるパラメータを比較する.

不確定度

♪the propagate_uncertainties パラメータは、不確実性の伝播をオンまたはオフにするために使用されても

  • もし None 結果に不確実性はありません

    >>> from astropy.nddata import StdDevUncertainty
    >>> ndd1 = NDDataRef(1, uncertainty=StdDevUncertainty(0))
    >>> ndd2 = NDDataRef(1, uncertainty=StdDevUncertainty(1))
    >>> ndd1.add(ndd2, propagate_uncertainties=None).uncertainty is None
    True
    
  • もし False 結果は最初の発見の不確実性があるだろう。

    注釈

    設ける propagate_uncertainties=False 通常はご利用はお勧めしません。

  • もし True この2つの不確実性は NDUncertainty 伝播を実現するサブクラス.これは可能ですなぜなら StdDevUncertainty **

    >>> ndd1 = NDDataRef(1, uncertainty=StdDevUncertainty([10]))
    >>> ndd2 = NDDataRef(1, uncertainty=StdDevUncertainty([10]))
    >>> ndd1.add(ndd2, propagate_uncertainties=True).uncertainty  
    StdDevUncertainty([14.14213562])
    

関連性のある不確実性

もし propagate_uncertainties はい。 True 1つの論点を与えることもできます uncertainty_correlation それがそうです。 StdDevUncertainty 自分で相関を追跡することはできませんが、正しい結果の不確実性を評価することができます(正しければ correlation 出しました。

デフォルト設定 (0 )は関連していないことを表します 1 相関平均値と相関平均値 -1 逆相関の。もし1つ与えたら numpy.ndarray それは要素相関係数を表さなければならない。

実例.

関連性がない場合には、減算する NDDataRef 事例自体は非ゼロ不確実性をもたらす:

>>> ndd1 = NDDataRef(1, uncertainty=StdDevUncertainty([10]))
>>> ndd1.subtract(ndd1, propagate_uncertainties=True).uncertainty  
StdDevUncertainty([14.14213562])

与えられた相関の場合 1 (有意な相関があるので)正確な不確実性を与える 0 **

>>> ndd1 = NDDataRef(1, uncertainty=StdDevUncertainty([10]))
>>> ndd1.subtract(ndd1, propagate_uncertainties=True,
...               uncertainty_correlation=1).uncertainty  
StdDevUncertainty([0.])

これは等価操作と一致する ndd1 * 0 **

>>> ndd1.multiply(0, propagate_uncertainties=True).uncertainty 
StdDevUncertainty([0.])

警告

ユーザは、適切な値または配列を手動で計算または知って、それを渡す必要がある uncertainty_correlation それがそうです。この実装は、一般的な一次誤差伝播式に従う。例えば、以下を参照してください。 Wikipedia それがそうです。

要素間の関連を与えることもできます:

>>> ndd1 = NDDataRef([1,1,1,1], uncertainty=StdDevUncertainty([1,1,1,1]))
>>> ndd2 = NDDataRef([2,2,2,2], uncertainty=StdDevUncertainty([2,2,2,2]))
>>> ndd1.add(ndd2,uncertainty_correlation=np.array([1,0.5,0,-1])).uncertainty  
StdDevUncertainty([3.        , 2.64575131, 2.23606798, 1.        ])

それらの間の関連性は np.array([1, 0.5, 0, -1]) 第1の要素が完全に相関していることを表し、第2の要素は部分的に関連しており、第3の要素は関連しておらず、第4の要素は逆相関である。

単位的不確実性

StdDevUncertainty データの単位が不確実性の単位と異なっていても,正確な誤り伝播を実現する.

>>> ndd1 = NDDataRef([10], unit='m', uncertainty=StdDevUncertainty([10], unit='cm'))
>>> ndd2 = NDDataRef([20], unit='m', uncertainty=StdDevUncertainty([10]))
>>> ndd1.subtract(ndd2, propagate_uncertainties=True).uncertainty  
StdDevUncertainty([10.00049999])

しかしデータに変換できる単位が必要です