注釈
クリック here 完全なサンプルコードをダウンロードします
最初から非常に大きな協力ファイルを作成します¶
この例は、以下のコマンドを使用して、最初から大きなファイル(メモリに格納可能なサイズよりも大きい)を作成する方法を示しています。 astropy.io.fits
それがそうです。
作者:エリック·ブライ
ライセンス:BSD
一般に、単一の画像FITSファイルを作成するためには、以下の動作を実行する必要がある。
import os
import numpy as np
from astropy.io import fits
data = np.zeros((40000, 40000), dtype=np.float64)
hdu = fits.PrimaryHDU(data=data)
そして使って astropy.io.fits.writeto()
方法新しいファイルをディスクに書きます。
hdu.writeto('large.fits')
しかし、40000 x 40000倍精度配列はほぼ12 GBです!ほとんどのシステムは、ディスクに書き込むだけでメモリにそれを作成することはできません。このような大きなファイルを効率的に作成するためには、いくつかの追加的な作業といくつかの仮定が必要である。
まず,タイトルに含まれるキーワードがどの程度大きいか(たとえば,いくつのキーワードがあるか)を予測することが有用である.FITSヘッダは、2880バイトブロックの形態で書き込まれなければならず、各ブロックは、36個のキーワード(最後のブロック内のENDキーワードを含む)を収容するのに十分である。典型的なヘッダは1~4つのブロックを含むが、より多くなる場合がある。
FITSファイルを書き込む最初のことはヘッダであるため,ファイル全体のサイズを調整することなく,新たなキーワードを追加するのに十分なパディングを持つために十分なヘッダブロックを書き込むことが望ましい.ヘッダがデフォルトで4つのブロックを使用することを望むと仮定します。そして,Astropyを除いて自動的に追加された末尾カードを見出しを作成し,36*4枚のカードに充填する.
HDUを初期化するためのスタブ配列を作成します。その正確な大きさは関係ありません。必要な次元数を持っていればいいです。
data = np.zeros((100, 100), dtype=np.float64)
hdu = fits.PrimaryHDU(data=data)
header = hdu.header
while len(header) < (36 * 4 - 1):
header.append() # Adds a blank card to the end
現在,NAXISnキーワードを必要な配列サイズに調整し,ヘッダファイルのみをファイルに書き込む.使用 hdu.writeto()
方法により、Astpy“ヘルプ”はNAXISnキーワードをリセットして仮想配列のサイズに一致させる。これは、有効なFITファイルのみが書き込まれることを確実にするために努力しているからだ。逆に私たちは astropy.io.fits.Header.tofile
方法:
header['NAXIS1'] = 40000
header['NAXIS2'] = 40000
header.tofile('large.fits')
最後に,文書末尾をデータ長(タイトル長を加える)に合うように長くする.多くのシステムでは,ファイルの末尾を探してシングルバイトを書き込むことで,以下のように非常に効率的にこの操作を行うことができる.
with open('large.fits', 'rb+') as fobj:
# Seek past the length of the header, plus the length of the
# Data we want to write.
# 8 is the number of bytes per value, i.e. abs(header['BITPIX'])/8
# (this example is assuming a 64-bit float)
# The -1 is to account for the final byte that we are about to
# write:
fobj.seek(len(header.tostring()) + (40000 * 40000 * 8) - 1)
fobj.write(b'\0')
もっと広く言えばこう書くことができます
shape = tuple(header[f'NAXIS{ii}'] for ii in range(1, header['NAXIS']+1))
with open('large.fits', 'rb+') as fobj:
fobj.seek(len(header.tostring()) + (np.product(shape) * np.abs(header['BITPIX']//8)) - 1)
fobj.write(b'\0')
現代のオペレーティングシステムでは、これは、40000 x 40000イメージを保存するために必要な~12 GBまで、ファイル(タイトルの後)にゼロパディングを使用することになります。スパースなファイル作成をサポートするファイルシステム(ほとんどのLinuxファイルシステムですが、ほとんどのMacで使用されているHFS+ファイルシステムではありません)では、非常に迅速で効率的な動作です。他のシステムでは、あなたのマイル数が違うかもしれない。
これは大きな文書を構築する唯一の方法ではないが、最も安全な方法の一つかもしれない。この方法は、少し注意するだけで、大型マルチ拡張FITファイルを作成するためにも使用することができます。
最後に、私たちが作成したファイルを削除します。
os.remove('large.fits')
スクリプトの総実行時間: (0分0.000秒)