IT技術で仕事を減らしたい!

ITエンジニアのメモ+α

macOS 仮想環境のWindowsでのWSL設定

どうも、nippa です。

macOS 上に VMware / VirtualBox で Windows11 をインストールして、WSL を利用しよう と思い試行錯誤しました。

どうしても WSL の環境を用意する必要があったのですが、すんなりとはいかなかったの と、なかなか情報もなかったので、まとめて置こうと思います。

macOS 上で Windows + WSL の環境をつくる人もそういないと思いますが。

環境

  • macOS 14.4
  • Virtual Box 7.0

WSL のバージョンについて

WSL1 と WSL2 の違いですが、以下の通りです。

  • WSL1: Linux カーネルをエミュレートしており、Windows のファイルシステムと直接統 合されている。起動が早く、Windows と Linux 間のファイルのやり取りが速いが、ネ イティブの Linux カーネルではないため、完全な互換性がない。

  • WSL2: 実際の Linux カーネルを仮想マシン上で実行しており、Linux アプリケーショ ンの互換性が向上している。一方で、仮想化技術を使用するため、WSL1 に比べて起動 が少し遅く、Windows と Linux 間のファイルのやり取りが若干遅くなることがある。

WSL2 では Linux カーネルを実際に動かしていますので、Linux を利用しているのと同じ ですが、WSL1 では Linux Like な環境を動かしていると認識しておけば良いと思います 。この差が環境構築にも影響します。

仮想環境上の Windows での WSL の利用

WSL の対応状況

Microsoft のページに仮想環境(VMware/VirtualBox)での WSL の対応状況が記載されて いました。

https://learn.microsoft.com/ja-jp/windows/wsl/compare-versions

仮想環境上では WSL1 は対応しているが、WSL2 は対応できていないということです。

Hypervisor 上で Hypervisor を動かすのはなかなか大変ということだと思います。

仮想環境の Windows での WSL の有効化

Windows11 では WSL のバージョンは2がデフォルトになっています。

仮想環境上で WSL を利用するには、WSL1 に変更して利用する必要があります。以下の手 順書 WSL の有効化をしていきます。

  1. wsl のインストール

    PowerShell を開いて、以下のコマンドを実行して wsl のコマンドをインストールし ます。

   wsl --install

  1. WSL のバージョンの設定

    現在のところ、仮想環境の Windows では WSL1 のみが対応しています。Windows11 で はデフォルトがバージョン2もしくは、設定されていないので、バージョン1に設定 します。

    まず、WAS のデフォルトのバージョンが設定されているかを確認します。

   wsl -l -v

   # 出力結果
   Linux 用 Windows サブシステムにインストールされているディストリビューションはありません。

デフォルトをバージョン 1 にセットします。

   wsl --set-default-version 1

   # 出力結果
   この操作を正しく終了しました。

以下のようなエラーが出る場合があります。この場合、Windows の Linux サブシステ ムが有効化されていないことが原因です。

   WSL1 は、現在のマシン構成ではサポートされていません。
   WSL1 を使用するには、"Linux 用 Windows サブシステム" オプション コンポーネントを有効にしてください。
   エラー コード: Wsl/WSL_E_WSL1_NOT_SUPPORTED

有効化は「コントロールパネル」-「プログラム」-「プログラムと機能」-「Windows の機能の有効化または無効化」から「Linux 用 Windows サブシステム」にチェックを いれるか、下記コマンドで有効化し、マシンを再起動で解決できます。

   Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

  1. WSL 用のディストリビューションのインストール

    インストール可能なディストリビューションの確認をしてインストールします。

   # ディストリビューションの確認
   wsl -l --online

   # 出力結果
   NAME                   FRIENDLY NAME
   Ubuntu                 Ubuntu
   Debian                 Debian GNU/Linux
   kali-linux             Kali Linux Rolling
   Ubuntu-18.04           Ubuntu 18.04 LTS
   Ubuntu-20.04           Ubuntu 20.04 LTS
   Ubuntu-22.04           Ubuntu 22.04 LTS
   openSUSE-Tumbleweed    openSUSE Tumbleweed

   # ディストリビューションのインストール
   wsl --install Ubuntu22.04 1

これで WSL(ubuntu22.04 アプリ)が起動できればインストール完了になります。

WSL2 をインストールして実行した場合のエラー

WSL2 をインストールして実行すると以下のようなエラーが発生します。WSL1 にバージョ ンを変更してインストールしてください。

Installing, this may take a few minutes...
WslRegisterDistribution failed with error: 0x80370102
Please enable the Virtual Machine Platform Windows feature and ensure virtualization is enabled in the BIOS.
For information please visit https://aka.ms/enablevirtualization
Press any key to continue...

感想

今回、macOS で 仮想環境の Windows11 に WSL をインストールしました。情報が少なく 手間取ったので、対応方法を残しておきます。

仮想環境の Windows が WSL2 に対応するとこのような作業はなくなると思いますが、ま だしばらくは難しそうなのでこの方法を試してみてください。

ではでは、また次回。

Windows WSL2のインストール

どうも、nippa です。

Windows で WSL2(Windows Subsystem for Linux 2)の環境セットアップしようと思いまし た。

環境セットの手順をメモしておこうと思います。

環境

WSL2 のインストール

PowerShellを管理者モードで開き、以下のコマンドを実行します。

wsl --install

利用できるディストリビューションを確認します。

wsl --list --online

# インストール可能なリスト表示
NAME                     FRIENDLY NAME
Ubuntu                   Ubuntu
Debian                   Debian GNU/Linux
kali-linux               Kali Linux Rolling
Ubuntu-18.04             Ubuntu 18.04 LTS
Ubuntu-20.04             Ubuntu 20.04 LTS
Ubuntu-22.04             Ubuntu 22.04 LTS
openSUSE-Tumbleweed      openSUSE Tumbleweed

以下のコマンドでディストリビューションを指定してインストールします。

wsl.exe --install <Distro>

# Ubuntuをインストールする場合のコマンド
wsl.exe --install Ubuntu

アプリからインストールしたディストリビューション名のアプリを起動で、利用できるよ うになります。

ディストリビューションの削除

ディストリビューションは「設定」-「アプリ」から削除することができます。

不要になったディストリビューションが完全に削除されるまでには少し時間がかかります 。

感想

仮想環境の Windows でで何度か WSL2 をインストールしていて、毎回調べているので備 忘録として、記事にしておきます。

ではでは、また次回。

Python httpxを使った非同期処理

どうも、nippa です。

Web サービスでは、JavaScript で非同期処理が活発に使われています。

最近では Python でも非同期処理が比較的簡単に利用できるようになってきましたので、 今回は requests と同じような扱いができる httpx での非同期処理を行ってみたいと思 います。

環境

  • macOS 14.1
  • httpx 0.26.0

httpx の特徴

Python3.5 以降で async/await が導入され、Python でも非同期処理が実現可能でした。

httpx は Python で HTTP リクエストを行うための標準的なライブラリである requests と同じインターフェースを持つライブラリで、requests を利用している方には非常に親 しみやすいライブラリとなっています。

また、同期(ブロッキング)/非同期(ノンブロッキング)処理どちらにも対応していま す。

httpx の利用

requests と同じインターフェースなので、そこまで取り扱いは非常に簡単です。

検証準備

以下のような簡単な モック用の API サーバ(mock_server.py)をローカルで作成して、こ のサーバーに対して同期・非同期処理のパフォーマンスを検証してみます。

from flask import Flask, jsonify, request

app = Flask(__name__)

mock_data: dict[int, dict] = {
    1: {"name": "User 1", "email": "[email protected]"},
    2: {"name": "User 2", "email": "[email protected]"},
    3: {"name": "User 3", "email": "[email protected]"},
}


@app.route("/users", methods=["GET"])
def get_items():
    return jsonify(mock_data)


@app.route("/users/<int:user_id>", methods=["GET"])
def get_item(user_id):
    user = mock_data.get(user_id)
    if user:
        return jsonify(user)
    else:
        return jsonify({"error": "Not found"}), 404


@app.route("/users", methods=["POST"])
def add_item():
    if (new_user := request.json) is None:
        return jsonify({"error": "Bad request"}), 400

    new_user_id = max(mock_data.keys()) + 1
    mock_data[new_user_id] = new_user
    return jsonify({"user_id": new_user_id, "user_info": new_user}), 201


@app.route("/users/<int:user_id>", methods=["PUT"])
def update_item(user_id: int):
    if (new_user := request.json) is None:
        return jsonify({"error": "Bad request"}), 400

    if user_id in mock_data:
        mock_data[user_id] = new_user
        return jsonify(mock_data[user_id])
    else:
        return jsonify({"error": "Not found"}), 404


@app.route("/users/<int:user_id>", methods=["DELETE"])
def delete_item(user_id: int):
    if user_id in mock_data:
        deleted_item = mock_data.pop(user_id)
        return jsonify({"message": "User deleted", "user_info": deleted_item})
    else:
        return jsonify({"error": "Not found"}), 404


if __name__ == "__main__":
    app.run(debug=True)

flask のインストール・モックサーバの起動は以下の通りです。

# flaskのインストール
poetry add flask

# モックサーバの起動
poetry run python mock_server.py

同期(ブロッキング)処理

httpx での同期処理でモックサーバへのアクセスとしては以下のようなになります。

import httpx


BASE_URL = "http://localhost:5000/users"


def get_users_sync() -> dict:
    URL = BASE_URL
    try:
        response = httpx.get(URL)
        response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


def get_user_sync(user_id: int) -> dict:
    URL = f"{BASE_URL}/{user_id}"
    try:
        response = httpx.get(URL)
        response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


def post_sync() -> dict:
    URL = BASE_URL
    try:
        response = httpx.post(URL, json={"name": "John", "age": 30, "email": "[email protected]"})
        response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


def put_sync(user_id: int) -> dict:
    URL = f"{BASE_URL}/{user_id}"
    try:
        response = httpx.put(URL, json={"name": "John", "age": 30, "email": "[email protected]"})
        response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


def delete_sync(user_id: int) -> dict:
    URL = f"{BASE_URL}/{user_id}"
    try:
        response = httpx.delete(URL)
        response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


def main():
    print("user一覧取得")
    users = get_users_sync()
    print(users)

    print("新規ユーザー追加")
    user = post_sync()

    print("user一覧取得")
    users = get_users_sync()
    print(users)

    print("user詳細の確認")
    put_sync(user["user_id"])
    user_info = get_user_sync(user["user_id"])
    print(user_info)

    print("userの削除")
    delete_sync(user["user_id"])

    print("user一覧取得")
    users = get_users_sync()
    print(users)


if __name__ == "__main__":
    main()

非同期(ノンブロッキング)処理

非同期処理でのコードは以下のようになります。

import httpx
import asyncio


BASE_URL = "http://localhost:5000/users"


async def get_users_async() -> dict:
    URL = BASE_URL
    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(URL)
            response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


async def get_user_async(user_id: int) -> dict:
    URL = f"{BASE_URL}/{user_id}"
    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(URL)
            response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


async def post_async() -> dict:
    URL = BASE_URL
    try:
        async with httpx.AsyncClient() as client:
            response = await client.post(URL, json={"name": "John", "age": 30, "email": "[email protected]"})
            response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


async def put_async(user_id: int) -> dict:
    URL = f"{BASE_URL}/{user_id}"
    try:
        async with httpx.AsyncClient() as client:
            response = await client.put(URL, json={"name": "John", "age": 30, "email": "[email protected]"})
            response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


async def delete_async(user_id: int) -> dict:
    URL = f"{BASE_URL}/{user_id}"
    try:
        async with httpx.AsyncClient() as client:
            response = await client.delete(URL)
            response.raise_for_status
        return response.json()
    except Exception as e:
        print(f"Error: {e}")
        return {}


async def main():
    print("user一覧取得")
    users = await get_users_async()
    print(users)

    print("新規ユーザー追加")
    user = await post_async()

    print("user一覧取得")
    users = await get_users_async()
    print(users)

    print("user詳細の確認")
    await put_async(user["user_id"])
    user_info = await get_user_async(user["user_id"])
    print(user_info)

    print("userの削除")
    await delete_async(user["user_id"])

    print("user一覧取得")
    users = await get_users_async()
    print(users)


if __name__ == "__main__":
    asyncio.run(main())

今回の場合、1 ユーザに対して実行するため、非同期処理としてはとくにパフォーマンス が高くなるわけではありません。

async/await のオーバーヘッド分パフォーマンスが落ちる場合もあります。

並行して同じ処理したり、同時実行できる処理を並行して行うときの場合には、効果を発 揮します。

使い所には注意が必要です。

感想

httpx の開発は 2019 年頃から始まっていますが、今後メジャーになっていくライブラリ だと思っています。

API のパフォーマンスを気にする場合には、是非利用を検討してみてください。

ではでは、また次回。

Windowsでのpyenvのトラブル解決法

どうも、nippa です。

Windows の WSL2 上で python の仮想環境を構築したく、pyenv をインストールして python の仮想環境を管理しようとしたころ、python の build がすんなりできなかった ので備忘録代わりに記事にしておきます。

環境

Pyenv のインストール

  1. git でソースコードを clone する
   git clone https://github.com/pyenv/pyenv.git ~/.pyenv
  1. pyenv の初期化
   pyenv init
  1. ログインシェルの再起動
   exec -l $SHELL
  1. pyenv の拡張機能(update 機能)のインストール

    pyenv 自体のアップデートを簡単にするため拡張機能の update のサブコマンドをイ ンストールします。

   git clone https://github.com/pyenv/pyenv-update.git $(pyenv root)/plugins/pyenv-update

Pyenv で python 仮想環境の構築

インストール可能な Python バージョンを確認します。

pyenv install --list

素の python の場合、バージョン番号になります。anaconda、miniconda もインストール できるので、環境の後始末にも便利なので、素でインストールするより後始末が簡単です 。

pyenv install 3.11.2

インストールした python バージョンを global にセットします。ユーザーログイン後、 デフォルトで使われる python になります。

# global環境のpythonを指定します。
python global 3.11.2

# 指定されているかの確認をします。
pyenv versions

Python のビルドで遭遇したエラー

  1. C 言語のコンパイルラーが見つからない

    以下のコマンドで、C コンパイラをインストールします。

   sudo apt update
   sudo apt upgrade
   sudo apt install gcc
  1. make コマンドが見つからない

    以下のコマンドで、make コマンドをインストールします。

   sudo apt install make
  1. 複数の開発用のライブラリが不足している

    python の標準ライブラリで必要な開発用をインストールします。

   sudo apt update
   sudo apt upgrade
   sudo apt install build-essential libbz2-dev libdb-dev libffi-dev libgdbm-dev liblzma-dev libncursesw5-dev libreadline-dev libsqlite3-dev libssl-dev tk-dev uuid-dev zlib1g-dev

上記の対応で、python の build に必要なコマンド・ライブラリはインストールできます 。

感想

今回、Windows の WSL で python の仮想環境を作る必要があり、生じたトラブルをまと めておきました。

知っていればどうってことはありませんが、知らないと苦労します。

あとから、python が動かないとかもありますので、環境は正しく構築しておきましょう 。

ではでは、また次回。

Python FITSファイルの操作

どうも、nippa です。

天文分野でよく使われれる FITS 形式のファイルを操作する必要があり、記事にまとめて おきたいと思います。

FITS 形式のファイルを扱うにはいくつかライブラリがあります。

  • astropy: Python
  • FITSIO: Python
  • CFITSIO: C 言語、Fortran 用のライブラリ

今回、Python での操作を前提として、astropy を利用して操作したいと思います。

環境

FITS ファイル形式

FITS ファイルは複数の「ヘッダーデータユニット」(HDU)で構成されています。各 HDU は、ヘッダー部とデータ部の 2 つのセクションから成り立っています。

ヘッダーは ASCII テキストで記述されており、データの詳細が含まれています。データ 部分はバイナリ形式で記述されており、任意の形式の配列データが含まれて言います。

astropy を利用した FITS ファイルの操作

astropy のインストール

  • pip インストール
  pip install astropy
  • poetry インストール
  poetry add astropy

FITS ファイルのサンプルの取得

NASA のサイトから FITS ファイルのサンプルを取得します。

https://fits.gsfc.nasa.gov/fits_samples.html

ブラウザから取得することもできます。

  • curl での取得
  curl -o WFPC2u5780205r_c0fx.fits https://fits.gsfc.nasa.gov/samples/WFPC2u5780205r_c0fx.fits
  • wget での取得
  wget https://fits.gsfc.nasa.gov/samples/WFPC2u5780205r_c0fx.fits

FITS ファイルの読み込み

astorpy.io を利用して、データを読み込みます。

from astropy.io import fits

file_name = "WFPC2u5780205r_c0fx.fits"
hdul = fits.open(file_name)

FITS ファイルのヘッダー情報の表示

header 情報は dict 形式として取得できます。

from astropy.io import fits

file_name = "WFPC2u5780205r_c0fx.fits"
hdul = fits.open(file_name)

header = hdul[0].header
for key, value in header.items():
     print(f"{key}: {value}")

実行すると以下のような出力がされます。

SIMPLE: True
BITPIX: -32
NAXIS: 3
NAXIS1: 200
NAXIS2: 200
NAXIS3: 4
EXTEND: True
COMMENT:   FITS (Flexible Image Transport System) format is defined in 'Astronomy
COMMENT:   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H
BSCALE: 1.0
BZERO: 0.0
OPSIZE: 2112
ORIGIN: STScI-STSDAS
FITSDATE: 2004-01-09
FILENAME: u5780205r_cvt.c0h
ALLG-MAX: 3777.701
ALLG-MIN: -73.19537
ODATTYPE: FLOATING
SDASMGNU: 4
CRVAL1: 182.6311886308
CRVAL2: 39.39633673411
CRPIX1: 420.0
CRPIX2: 424.5
CD1_1: -1.06704e-06
CD1_2: -1.25958e-05
CD2_1: -1.26016e-05
CD2_2: 1.06655e-06
DATAMIN: -73.19537
DATAMAX: 3777.701
MIR_REVR: True
ORIENTAT: -85.16
FILLCNT: 0
ERRCNT: 0
FPKTTIME: 51229.798574
LPKTTIME: 51229.798742
CTYPE1: RA---TAN
CTYPE2: DEC--TAN
DETECTOR: 1
DEZERO: 316.6452
BIASEVEN: 316.6715
BIASODD: 316.6189
GOODMIN: -5.064006
GOODMAX: 2552.17
DATAMEAN: 0.4182382
GPIXELS: 632387
SOFTERRS: 0
CALIBDEF: 1466
STATICD: 0
ATODSAT: 16
DATALOST: 0
BADPIXEL: 0
OVERLAP: 0
PHOTMODE: WFPC2,1,A2D7,LRF#4877.0,,CAL
PHOTFLAM: 3.44746e-16
PHOTZPT: -21.1
PHOTPLAM: 4884.258
PHOTBW: 20.20996
MEDIAN: -0.175651
MEDSHADO: -0.121681
HISTWIDE: 1.033711
SKEWNESS: -1.983727
MEANC10: 0.12958
MEANC25: 0.3129676
MEANC50: 0.4577668
MEANC100: 0.3916293
MEANC200: 0.3115222
MEANC300: 0.3295493
BACKGRND: -0.3676353
ORIGIN: NOAO-IRAF FITS Image Kernel December 2001
DATE: 2004-01-09T03:26:36
IRAF-TLM: 03:26:36 (09/01/2004)
FILETYPE: SCI
:
TELESCOP: HST
INSTRUME: WFPC2
EQUINOX: 2000.0
:
:       / WFPC-II DATA DESCRIPTOR KEYWORDS
:
ROOTNAME: u5780205r
PROCTIME: 53013.14019676
OPUS_VER: OPUS 14.5a
CAL_VER:
:
:       / SCIENCE INSTRUMENT CONFIGURATION
:
MODE: FULL
SERIALS: OFF
:
:       / IMAGE TYPE CHARACTERISTICS
:
IMAGETYP: EXT
CDBSFILE: NO
PKTFMT: 96
:
:       / FILTER CONFIGURATION
:
FILTNAM1: FR533P15
FILTNAM2:
FILTER1: 69
FILTER2: 0
FILTROT: 15.0
LRFWAVE: 4877.0
:
:       / INSTRUMENT STATUS USED IN DATA PROCESSING
:
UCH1CJTM: -88.2569
UCH2CJTM: -88.6697
UCH3CJTM: -88.3028
UCH4CJTM: -88.7671
UBAY3TMP: 13.2302
KSPOTS: OFF
SHUTTER: A
ATODGAIN: 7.0
:
:       / RSDP CONTROL KEYWORDS
:
MASKCORR: COMPLETE
ATODCORR: COMPLETE
BLEVCORR: COMPLETE
BIASCORR: COMPLETE
DARKCORR: COMPLETE
FLATCORR: SKIPPED
SHADCORR: OMIT
DOSATMAP: OMIT
DOPHOTOM: COMPLETE
DOHISTOS: OMIT
OUTDTYPE: REAL
:
:       / CALIBRATION REFERENCE FILES
:
MASKFILE: uref$f8213081u.r0h
ATODFILE: uref$dbu1405iu.r1h
BLEVFILE: ucal$u5780205r.x0h
BLEVDFIL: ucal$u5780205r.q1h
BIASFILE: uref$j9a1612mu.r2h
BIASDFIL: uref$j9a1612mu.b2h
DARKFILE: uref$j2g1549cu.r3h
DARKDFIL: uref$j2g1549cu.b3h
FLATFILE: uref$f4i1559cu.r4h
FLATDFIL: uref$f4i1559cu.b4h
SHADFILE: uref$e371355eu.r5h
PHOTTAB: u5780205r_c3t.fits
GRAPHTAB: mtab$n9i1408hm_tmg.fits
COMPTAB: mtab$nc809508m_tmc.fits
:
:       / DEFAULT KEYWORDS SET BY STSCI
:
SATURATE: 4095
USCALE: 1.0
UZERO: 0.0
:
:       / READOUT DURATION INFORMATION
:
READTIME: 464
:
:       / PLANETARY SCIENCE KEYWORDS
:
PA_V3: 49.936909
RA_SUN: 333.7194516616
DEC_SUN: -10.86675160382
EQNX_SUN: 2000.0
MTFLAG: False
EQRADTRG: 0.0
FLATNTRG: 0.0
NPDECTRG: 0.0
NPRATRG: 0.0
ROTRTTRG: 0.0
LONGPMER: 0.0
EPLONGPM: 0.0
SURFLATD: 0.0
SURFLONG: 0.0
SURFALTD: 0.0
:
:       / PODPS FILL VALUES
:
PODPSFF: 0
STDCFFF: 0
STDCFFP: 0x5569
RSDPFILL: -100
:
:       / EXPOSURE TIME AND RELATED INFORMATION
:
UEXPODUR: 300
NSHUTA17: 1
DARKTIME: 300.0
UEXPOTIM: 16880
PSTRTIME: 1999.051:19:08:37
PSTPTIME: 1999.051:19:16:37
:
:       / EXPOSURE INFORMATION
:
SUNANGLE: 141.618347
MOONANGL: 126.698997
SUN_ALT: -31.523479
FGSLOCK: FINE
:
DATE-OBS: 1999-02-20
TIME-OBS: 19:03:13
EXPSTART: 51229.79390428
EXPEND: 51229.7973765
EXPTIME: 300.0
EXPFLAG: NORMAL
:
:       / TARGET & PROPOSAL ID
TARGNAME: NGC4151
RA_TARG: 182.6355
DEC_TARG: 39.40576666667
ECL_LONG: 164.096619
ECL_LAT: 36.623709
GAL_LONG: 155.079532
GAL_LAT: 75.062679
:
PROPOSID: 8019
PEP_EXPO: 02-030
LINENUM: 02.030
SEQLINE:
SEQNAME:
HISTORY:   MASKFILE=uref$f8213081u.r0h  MASKCORR=COMPLETED
HISTORY:   PEDIGREE=INFLIGHT 01/01/1994 - 15/05/1995
HISTORY:   DESCRIP=STATIC MASK - INCLUDES CHARGE TRANSFER TRAPS
HISTORY:   BIASFILE=uref$j9a1612mu.r2h  BIASCORR=COMPLETED
HISTORY:   PEDIGREE=INFLIGHT 29/08/98 - 21/08/99
HISTORY:   DESCRIP=not significantly different from j6e16008u.
HISTORY:   DARKFILE=uref$j2g1549cu.r3h  DARKCORR=COMPLETED
HISTORY:   PEDIGREE=INFLIGHT 16/02/1999 - 16/02/1999
HISTORY:   DESCRIP=Pipeline dark: 120 frame superdark with hotpixels from
HISTORY:   16/02/99
HISTORY:   FLATFILE=uref$f4i1559cu.r4h  FLATCORR=SKIPPED
HISTORY:   PEDIGREE=DUMMY  18/04/1995
HISTORY:   DESCRIP=All pixels set to value of 1. Not flat-fielded.
HISTORY:   PC1: bias jump level ~0.100 DN.
HISTORY:   The following throughput tables were used:
HISTORY:   crotacomp$hst_ota_007_syn.fits, crwfpc2comp$wfpc2_optics_006_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_lrf_004_syn.fits[wave#],
HISTORY:   crwfpc2comp$wfpc2_dqepc1_005_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_a2d7pc1_004_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_flatpc1_003_syn.fits
HISTORY:   The following throughput tables were used:
HISTORY:   crotacomp$hst_ota_007_syn.fits, crwfpc2comp$wfpc2_optics_006_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_lrf_004_syn.fits[wave#],
HISTORY:   crwfpc2comp$wfpc2_dqewfc2_005_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_a2d7wf2_004_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_flatwf2_003_syn.fits
HISTORY:   The following throughput tables were used:
HISTORY:   crotacomp$hst_ota_007_syn.fits, crwfpc2comp$wfpc2_optics_006_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_lrf_004_syn.fits[wave#],
HISTORY:   crwfpc2comp$wfpc2_dqewfc3_005_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_a2d7wf3_004_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_flatwf3_003_syn.fits
HISTORY:   The following throughput tables were used:
HISTORY:   crotacomp$hst_ota_007_syn.fits, crwfpc2comp$wfpc2_optics_006_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_lrf_004_syn.fits[wave#],
HISTORY:   crwfpc2comp$wfpc2_dqewfc4_005_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_a2d7wf4_004_syn.fits,
HISTORY:   crwfpc2comp$wfpc2_flatwf4_003_syn.fits
CTYPE3: GROUP_NUMBER
CD3_3: 1
CD3_1: 0
CD1_3: 0
CD2_3: 0
CD3_2: 0

FITS ファイルのデータ部分の取得

以下のコードでデータ部分を取得することができます。

サンプル FITS ファイルでは 200x200 で 4 つのイメージが格納されています。以下のコ ードでは、1 つ目のデータを取得しています(data[0])。

from astropy.io import fits

file_name = "data/WFPC2u5780205r_c0fx.fits"
hdul = fits.open(file_name)

data = hdul[0].data[0]

print(data)

FITS データの描画

matplotlib を利用して、FITS データを描画します。

matplotlib のインストール

  • pip インストール
  pip install matplotlib
  • poetry インストール
  poetry add matplotlib

matplotlib での描画

以下のコードで FITS データを描画できます。

import matplotlib.pyplot as plt
from astropy.io import fits

file_name = "data/WFPC2u5780205r_c0fx.fits"
hdul = fits.open(file_name)

data = hdul[0].data[0]

plt.figure(figsize=(10, 10))
plt.imshow(data, cmap="gray")
plt.colorbar()

plt.show()
plt.close()
hdul.close()

FITSデータの描画

感想

今回、python で astropy を利用して FITS ファイルを読み込み、ヘッダー情報の取得、 データの取得、データの描画までまとめました。

ここまで操作できれば、あとの取り扱いはデータ処理になります。参考にしてください。

ではでは、また次回。