表ヘッダインタフェース変換ガイド

注釈

本ガイドは、最初にPyFITSバージョン3.1に含まれていましたが、例が更新されたにもかかわらず、多くの場所でPyFITSが参照されています astropy.io.fits それがそうです。AstropyはPyFITS 3.1ヘッダインタフェースを用いてきたが,ここでは情報目的に用いられている.

PyFITS v 3.1はほぼ完全に書き換えられている Header インターフェースです。新しいインタフェースは旧インタフェースと大きく互換性があるにもかかわらず(設計上の類似点であっても,後方互換性の支援によるものであっても),十分な違いがあるため,新しいインタフェースを網羅的に解釈する必要がある.

背景

Prior to 3.1, PyFITS users interacted with FITS headers by way of three different classes: Card, CardList, and Header.

Cardクラスは,キーワード,値,アノテーションを持つ単一のヘッダカードを表す.これはまた、タイトルから読み取られた80文字の文字列または“カード画像”を与えるFITタイトルカードを解析するすべての機構を含む。

CardListクラスは実際にPythonのサブクラスです list 内蔵されています。タイトルを構成するカードの実際のリストを表すのが本来の意味である.すなわち,カードがタイトルに出現する物理的な順序でカードの順序リストを表す.これは、リストに新しいカードを挿入して追加する一般的なリスト方法をサポートします。それはまだ支持されています dict -キーワードアクセスのように、 cardlist['KEYWORD'] リストに所与のキーワードを有する最初のカードが戻ります。

実際,CardListクラスにはヘッダを操作するための機能が多く隠されている.HeaderクラスはさらにCardListのラッパのように,少し抽象的である.これはまた、部分的に辞書のようなインタフェースを実現しているが、Headerの場合、キーワードルックアップは、Cardオブジェクトではなく、キーワードに関連するHeader値を返し、Headerクラス上のほとんどのメソッドは、下位CardList上でいくつかの動作のみを実行する。

問題はユーザーが特定のことをすることができるということです only カード上の注釈を検索するか、または履歴のような繰り返しキーワードを有するアクセスカードのようなCardListに直接アクセスすることができる。もう1つの長期的に存在する誤り特性は,分割Headerオブジェクトが実際に新たなHeaderではなくCardListオブジェクトに返されることである.最も単純な用例を除いて,CardListオブジェクトを用いることは避けられないことが大きい.

しかし,CardListは実際には実装詳細であり,FITSファイルのいかなる要素も表しておらず,ヘッダファイル自体とは異なることが認識されている.FITSフォーマットに詳しいユーザはタイトルが何であるかを知っているが,“カードリスト”がタイトルとどのように異なるのかは不明であり,なぜ操作がタイトルオブジェクトを通過するのかは不明であり,CardListで実行されなければならない操作もある.

そこで,今回の再設計の主な目標は除去である CardList クラスはユーザが直接通過できるようにしています Header 物体です。これはまた、よりよく知られているデータ構造-順序マッピング(または)と可能な限り類似しようとしている OrderedDict Python)では、FITSフォーマットの特性を処理するにもかかわらず、FITSフォーマットに慣れていない新しいユーザが使用するために、多くの複雑さがあります。

警告のご利用はおすすめしておりません

古い方法があります Header クラスは使用されていないと表記されていますなぜならもっと多くの名前が付けられているからかもしれません PEP 8 -標準的な名前に適合するか、または新しい機能のために不要になります。コードが推奨されていない方法や機能を使用しているかどうかをチェックするには、ご利用ください python -Wd それがそうです。これはすべての廃棄警告をコンソールに出力するだろう。

ヘッダに関連する2つの最も一般的な破棄警告は、:

  • Header.has_key :PyFITS 3.0からPythonのように使用することは推奨されていません dict.has_key 賛成しません。マッピング対象におけるキーの存在をチェックするには、以下の操作を実行してください dict あるいは…。 Header 使用、使用 key in d 文法です。これはPythonの第一選択だった。

  • Header.ascardlist そして Header.ascard アクセスするために使われています CardList オブジェクトはヘッダの基礎とする.それらは依然として有効であるべきであり、フレームワークCardListに戻って実装されるべきであり、この実装は、ほとんどの古いCardList機能をサポートすべきである。しかしできるだけ多くのものを除去しようとしています直接訪問すれば Card タイトルを構成するオブジェクトが必要ですので、ご利用ください Header.cards カードの重畳器に戻ります以下にこの点の詳細を紹介する.

新しいヘッダデザイン

新しい Header クラスは dict via duck typing それがそうです。つまりそうではないにもかかわらず dict これは,すべての同じ方法とインタフェースを実現している.具体的には OrderedDict 挿入の順序が保留されているからである.しかし、Headerは、FITフォーマットに固有の多くの追加機能やアクションをサポートしています。なお,古いヘッダ実現にもdictのようなインタフェースがあるが,実現されていないことに注意すべきである. 全部です。 Dictインタフェースは,新しいヘッダが行ったようなものである.

ほとんどの場合、新しいヘッダの使用方法は辞書/マッピングと同様であるにもかかわらず、サポートされる。 list インターフェースです。類似リストのインタフェースは、いくつかの文脈では、ヘッダファイルの行動が値リストに類似しているので、他の文脈では、その行動はキーワードリストに類似しており、少数の文脈では、値リストに類似しているからである。 Card 物体です。これは新しい設計の最も難しい側面かもしれないが、これは論理的だ。

従来のヘッダ実装と同様に、整数インデックスアクセスがサポートされる: header[0] 最初のキーワードの値を返す.しかし、 Header.index() 方法は、ヘッダをキーワードリストと見なし、所与のキーワードのインデックスを返す。例えば:

>>> header.index('BITPIX')
2

Header.count() 似たような list.count また,キーワードをそのパラメータとする:

>>> header.count('HISTORY')
20

良い経験則はどの項も四角括弧を使ってアクセスできることです [] 返品 見出しでは,キーワードを用いてもインデックスを用いて検索してもよい.このような方法は index() そして count() タイトル中の項目の順序や数を扱う内容は,通常キーワードに関連している.最後にこのような方法は insert() そして append() 見出しのカードに新しいものを追加する作業。

類似リストの手法以外にも,多くの基本用例に対して,新しいHeaderクラスの動作方式は古い実現と非常に類似しており,あまり意外なことをもたらすことはないはずである.しかし違いもあります

  • 先と同様に,Header()初期化器は取得することができる. Card ヘッダのオブジェクトを充填します。しかし,現在ではどのような反復器も使用可能である.同様に注意すべきことは any 受信したHeaderメソッド Card オブジェクトはカードの代わりに2元グループや3タプルを受け取ることもできる.つまり1つは (keyword, value, comment) 元グループまたは (keyword, value) タプル(注釈が空であると仮定する)はCardオブジェクトの代わりにどこでも利用可能である.タイプが少ないので、これはさらに第一選択だ。例えば:

    >>> from astropy.io import fits
    >>> header = fits.Header([('A', 1), ('B', 2), ('C', 3, 'A comment')])
    >>> header
    A       =                    1
    B       =                    2
    C       =                    3 / A comment
    
  • 上の例に示すように repr() ヘッダ(すなわち,PythonコンソールでHeaderオブジェクトを式として入力したときに表示されるテキスト)に対しては,FITSファイルにヘッダが表示されるようにヘッダが表示される.これは、端子幅にかかわらず読み取り可能なように、各カードの後に改行を挿入する。そうなんです。 not 使用しなければならない print header これを見に来ました。中に入る header タイトル内容は、ファイルに表示されるように表示される(端末カードは表示されない)。

  • len(header) 現在サポート(以前は以下の操作を実行する必要があった len(header.ascard) )である。これは、空白カードを含むタイトル内のカード総数に戻るが、末尾カードは含まれない。

  • FITSは,通常誤りであるにもかかわらず,アノテーションや履歴などのコメントキーワードは除外した重複を持つキーワードをサポートしている.PyFITSは現在,重複したキーワードの読み出し,更新,削除をサポートしており,キーワードを単独で使用するのではなく,使用している. (keyword, index) 元グループです。例えば ('HISTORY', 0) 最初の歴史カードを表しています ('HISTORY', 1) 2枚目の履歴カードを表しています実際キーワードを単独で使うと (keyword, 0) それがそうです。現在,意外な重複項を削除することができ,以下のようになる.

    >>> del header[('NAXIS', 1)]
    

    これは,意外に重複したNAXISカードをタイトルから削除する.

  • 重複したキーワードがあっても、このようなキーワードを探す header['NAXIS'] キーワードの最初のコピーに関連する値は常に戻るが、コメントや履歴などのコメントキーワードには重複項があるはずである例外がある。だから…。 header['HISTORY'] 例えば、正しい順序で歴史値のシーケンス全体を返す。この値リストは任意のスライスが可能である.例えば、タイトルの最後の3つの履歴エントリを見る:

    >>> hdulist[0].header['HISTORY'][-3:]
      reference table oref$laf13367o_pct.fits
      reference table oref$laf13369o_apt.fits
    Heliocentric correction = 16.225 km/s
    
  • Subscript assignment can now be used to add new keywords to the header. Just as with a normal dict, header['NAXIS'] = 1 will either update the NAXIS keyword if it already exists, or add a new NAXIS keyword with a value of 1 if it does not exist. In the old interface this would return a KeyError if NAXIS did not exist, and the only way to add a new keyword was through the update() method.

    デフォルトの場合、このように追加された新しいキーワードは、タイトルの末尾に追加されるが、Fitに固有のいくつかの例外がある:

    • タイトルの末尾に追加の空白カードが含まれている場合、空白に新しいキーワードが追加されます。

    • タイトルがコメントカードリスト(例えば、一連の履歴カード)で終了した場合、これらのカードは末尾に保持され、コメントカードの前に新しいキーワードが挿入される。

    • コメントや履歴(または空キーワードの空文字列)のようなコメントキーワードがコメントキーワードである場合、 new コメントキーワードは、常に同じタイプの最後のコメントキーワードの後に追加されて付加される。例えば、歴史的キーワードは、最後の歴史的キーワードの後に常に置かれている。

      >>> header = fits.Header()
      >>> header['COMMENT'] = 'Comment 1'
      >>> header['HISTORY'] = 'History 1'
      >>> header['COMMENT'] = 'Comment 2'
      >>> header['HISTORY'] = 'History 2'
      >>> header
      COMMENT Comment 1
      COMMENT Comment 2
      HISTORY History 1
      HISTORY History 2
      

    これらの行為はキーワード代入の合理的なデフォルト行為を表し,その行為と update() 古いヘッダ実現では.他の代入方法を使うことで Header.set() そして Header.append() 後で紹介する方法です。

  • タプルを使用することもできますキーワードに注釈を与えながら

    >>> header['NAXIS'] = (2, 'Number of axis')
    

    これは、既存のキーワードの値および注釈を更新するか、または所与の値および注釈を有する新しいキーワードを追加する。

  • 新しいのがあります Header.comments この属性は、タイトル内のキーワードに関連するすべての注釈(コメントカードと混同しないように)を示す。これにより、特定のカード上の注釈を表示して更新することができます:

    >>> header.comments['NAXIS']
    Number of axis
    >>> header.comments['NAXIS'] = 'Number of axes'
    >>> header.comments['NAXIS']
    Number of axes
    
  • 見出しからキーワードを削除する際には,そのキーワードがすでに存在すると仮定してはならない.古いヘッダ実装では、この動作は、何の動作も暗黙的に実行されないであろう。後方互換性のためには,存在しないキーワードを削除してもよいが,警告を発する.未来にはこれは will 存在しないキーワードの削除を試みるように変更された場合には KeyError それがそうです。これはPython文の行動と一致するためである.したがって、キーワードを削除する前にキーワードが存在すると判断されない限り、以下の動作を実行することが望ましい。

    >>> try:
    ...     del header['BITPIX']
    ... except KeyError:
    ...     pass
    

    あるいは、もしあなたがもっとよく考えてから行くのが好きなら:

    >>> if 'BITPIX' in header:
    ...     del header['BITPIX']
    
  • del header 今はスライスをサポートしています。例えば、タイトルの最後の3つのキーワードを削除する:

    >>> del header[-3:]
    
  • 現在,2つのHeaderが等しいかどうかを比較することができる-以前は2つのHeaderオブジェクトが同じではなかった.今、それらが完全に同じ内容を含んでいれば、それらは平等に比較することができる。つまり、これは厳格な平等を必要とする。

  • いま‘+’演算子を使用して2つの見出しを追加することができ,この演算子は右側の見出しで拡張された左見出しのコピーを返す. extend() それがそうです。作業追加も可能である.

  • 通常,古いHeader APIとともに使用されるHeader.update()メソッドは,新たに名前を付けられている. Header.set() それがそうです。この変更を行う要因は非常に簡単である:Headerは実現した. dict インタフェースは,すでにupdate()という方法があるが,その振舞いは古いHeader.update()とは異なる.

    新しいupdate()の詳細な情報はAPI文書で読み取ることができるが,非常に類似している. dict.update それがそうです。それに渡されるパラメータを解析することにより,古いupdate()を後方に互換することもサポートされるため,既存のコードはただちに中断されることはない.でも、これは will それらが有効にされている場合、廃棄警告が出力される。初心者にとっては,すべてのupdate()呼び出しをset()に置き換えることが望ましい.新しいキーワードをタイトルに追加するために,現在直接与えられていることを思い出してもよい.基本的には使うのが好きです Header.set() 属性がキーワードを特定の位置に挿入または移動させる能力. before あるいは…。 after 論争する。

  • スライスインデックスを持つ見出しをスライスすると,スライスに含まれるそれらのカードのみを含む新しい見出しが返される.先に述べたように,過去に見出しを分割して1つのカードリストを返すというのは誤った機能である通常,スライスをサポートするオブジェクトはスライス時に同じタイプのオブジェクトを返すべきである.

    同様に、ワイルドカードキーワードは、CardListオブジェクトを返すために過去に使用され、現在、スライスと同様の新しいタイトルが返される。例えば:

    >>> header['NAXIS*']
    

    元のタイトルのNAXISおよびNAXISnカードのみを含む新しいタイトルを返します。

過渡提示

上の内容は多く見えるかもしれないが,PyFITSを用いてヘッダを操作する既存コードの大部分は更新する必要がなく,少なくともすぐに更新する必要はないはずである.最も一般的な操作は依然として同じだ。

以上のように,以下の命令を用いてコードを実行することは有用である. python -Wd 廃棄警告を有効にする-これはコード位置を更新する良い考えでなければならない。

もしあなたのコードがPyFITS 3.1と同時に古いバージョンをサポートできるPyFITSを必要とする場合、物事は少し複雑になりますが、あまり複雑ではありません-したがって、より多くのバージョンで使用を推奨しないインターフェースは削除されません。

  • 最初にすべき変更は、過去数年間すべてのPyFITSバージョンがサポートされてきたすべてのPyFITSバージョンの使用をキャンセルすることです。 Header.has_key それを交換して keyword in header 文法です。これはどんな判決にも価値があります dict.has_key 賛成しません。コード上で以下の正規表現を実行することは、多くの(すべてではない)場合に役立つ可能性がある:

    s/([^ ]+)\.has_key\(([^)]+)\)/\2 in \1/
    
  • できれば,Header.update()に対する任意の呼び出しをHeader.set()に置き換えてください(ただし,古いPyFITSバージョンをサポートする必要があれば,そのために気を使わなくてもよい).さらに、Header.update()の呼び出しがあれば、簡単な添字代入で置き換えることができます(例えば、 header['NAXIS'] = (2, 'Number of axes') )可能であれば、そうする。

  • 以下のコードを使用した任意のコードを検索する header.ascard あるいは…。 header.ascardlist() それがそうです。まず,このコードが本当にCardオブジェクトに直接作用する必要があるかどうかを決定する.もし状況が確かであれば、引き続きそれを変えてください header.cards -そんなに驚くことはないだろう古いバージョンをサポートする必要があれば、引き続きご利用いただけます header.ascard 今のところでは。

  • 見出しを分割するコードがある場合には、結果を取得し、それから新しい見出しオブジェクトを作成することが望ましい。例えば:

    >>> new_header = fits.Header(old_header[2:])
    

    これは,PyFITS<=3.0において,結果を用いて新たなHeaderオブジェクトを初期化することでHeaderをスライスしてCardListに返すという問題を回避している.これは両方の場合に有効である(PyFITS 3.1では,既存のヘッダで初期化されたヘッダはそれをコピーするだけである. list )。

  • 前述したように,キーワードを削除するコードを見つける del 彼らが考えてから行動するかどうかを確認してください (if keyword in header: )または許しを求める (try/except KeyError: )。

他のゴザス

  • 上述したように、入る必要はありません print header インタラクティブなPythonプロンプトにヘッダを表示する場合は、以下の操作を実行してください。中に入る >>> header これだけで十分です。Vbl.使用 print 通常は not ヘッダは、ヘッダカード間の改行子を含まないので、読み取り可能な方法で表示される。なぜならPythonには2つのタイプの文字列表現があるからです1つはユーザが呼び出したときに戻ってくるものです str(header) これは以下のような場合に自動的に発生します print 1つの変数ですHeaderクラスの場合、これは、文字通りFITSファイルに書かれているので、実際にはヘッダの文字列値を返し、そのファイルには改行が含まれていない。

    もう1つのタイプの文字列は呼び出していることを表す repr(header) それがそうです。♪the repr オブジェクトはオブジェクトの有用な文字列“表示”であり,本例ではタイトルの内容であるが,カード間に改行があり,末尾カードと末尾パッドが除去されている.ユーザがPythonプロンプトの下で変数を個別に入力すると、使用することなく print 電話します。

  • 現在バージョンのFITS基準(3.0)は4.2.1節で規定しているが,タイトル中の文字列値の末尾スペースは重要ではなく,無視すべきである.PyFITS<3.1 did 尾行スペースを重要とする。例えば、タイトルが含まれている場合:

    KEYWORD 1=‘値’

    それで? header['KEYWORD1'] 戻り文字列 'Value    ' 完全に正確で、追跡空間は無傷です。新しいヘッダインタフェースは,空白を自動的に剥離することでこの問題を修復するためである. header['KEYWORD1'] 戻ってきます。 'Value' それがそうです。

    しかし,IRAF CCDモザイクタスクは,フォーム中の一連のキーワードを用いたTNX世界座標系とZPX世界座標系の非標準WCSを表す約定を用いている. WATj_nnn 非線形歪み投影のための係数のテキスト記述を格納する。これは,自分のマイクロフォーマットを用いて係数を文字列として並べているが,文字列が長いため,いくつかに分類される WATj_nnn キーワードです。これらのキーワードの正しい組合せは,すべてのスペースを1文字ずつ処理する必要がある.このコミットメントはFITS規格でのスペースの規定処理を無視しているか,またはそれよりも早い.

    この問題を迂回するためにグローバル変数は fits.STRIP_HEADER_WHITESPACE 紹介されました。仮設定. fits.STRIP_HEADER_WHITESPACE.set(False) この問題の影響を受けたキーワードを読み込む前に,それらの値を返し,すべての添えスペースを保持する.

    将来バージョンのPyFITSは,コンテキストでこのようなコミットメントの使用を検出し,コミットメントによる操作を行うことが可能であるが,多くの場合,PyFITSのデフォルトアクションはFITS標準に従って操作される.