FITS文件结构与读取

FITS 文件简介

FITS (Flexible Image Transport System, 普适图像传输系统)是天文上常用的数据文件存储格式,可以用来存储图像、光谱、表格这一类的数据。

fits文件结构:

首先要知道fits文件由一个或多个HDU(Header/Data Units, 头、数据单元)的单元组成,其中第一个被称作Primary HDU(主HDU),主HDU可以包含1-999维的一个数组,数组数据的类型由头信息进行定义。典型的数据包括:2-D图像、1-D的光谱以及3-D的数据立方体。

主HDU后面还可以跟多个扩展HDU来存储其他内容。

每个HDU都由Header UnitData Unit 组成,Header Unit 是类似类似字典类型的数据结构,形式一般为:关键字名称=值/关键字相关的注释,包含此数据观测的时间、望远镜参数、天气条件之类的信息。 Data Unit 存放的就是数据了,如numpy数组。

光谱fits文件

以 Lamost 光谱文件为例,首先它的文件命包含此条光谱的一些信息,如“spec_55916_B5591606_sp01_01.fits”:“spec” 表示天文光谱,“55916” 表示本地修正儒略日(一种天文上时间表示的方法),“B5591606” 代表天区的编号,“sp01” 代表光谱仪的标号,“001” 代表光谱仪中光纤的编号。

它的HDU的Header Unit 中常用的字段有:

1
2
3
4
5
6
7
8
9
LONGITUD、LATITUDE:观测地点的经度、纬度
OBSID:唯一光谱编号
OBSDATE:观测目标的日期
PLANID:天区编号
LMJD:本地修正儒略日
FIBERID:光纤编号
OBJTYPE:所观测到的星体的类型
SN_U、SN_G、SN_R、SN_I、SN_Z:u、g、r、i、z波段的信噪比
Z: 红移值

Data Unit 是一个5行3909列的矩阵(不是所有光谱都是3909列),每一列代表一个波长,每一行代表一种属性,分别是:或标志位、与标志位、波长、倒方差、流量(顺序可能不同)。有两种fits格式,这里所说的是其中一种。

天体测光波段

波段 中心波长 λeff 半高全宽(FWHM,Δλ) 变体 说明
紫外
U 365nm 66nm u,u′,u∗
可见光
B 445nm 94nm b
G 464nm 128nm g,g′ 绿
V 551nm 88nm v,v′ 可见
R 658nm 138nm r,r′,R′,R
近红外
I 806nm 149nm i,i′,I
Z 900nm z,z′
Y 1020nm 120nm y
J 1220nm 213nm J′,Js
H 1630nm 307nm
K 2190nm 390nm K,K′,Ks, K8,nbK
L 3450nm 472nm L′,nbL′
中红外
M 4750nm 460nm M′,nbM
N 10500nm 2500nm
Q 21000nm 5800nm Q′

fits文件读取

利用astropy天文工具包读。

文件不需要解压,fits、gz和bz2的都可以直接读。

1
2
3
from astropy.io import fits
hdu = fits.open('spec-55859-F5902_sp01-001.fits') # 读取fits文件
header,data = hdu[0].header,hdu[0].data # 获取第0个hdu里的信息,

hdu.info() 能打印fits信息

读出来之后就可以用Matplotlib 把流量信息画出来,看一下光谱。图像的话应该也有相应的函数,不过我还没用到。

例子:

1
2
3
4
5
6
7
8
from astropy.io import fits
import matplotlib.pyplot as plt
data = fits.open('spec-55895-B9505_sp04-042.fits')
x = a.data[2] # 第3行是波长
y = a.data[0] # 第1行是光谱
print(len(x),len(y))
plt.plot(x,y)
plt.show()

结果:

image-20211008091827807

光谱fits文件

LAMOST发布的光谱fits文件有两种,一般见到的是第一种。

第一种里面一个hdu包含5行信息,有用的信息有两行,第一行是流量,第三行是波长,如下图(下图软件叫fv):

image-20211007194022625

另一种有两个hdu,第0个是信息,包含6行,第一行是流量,波长信息可以计算出来,hdu[0].header头信息中包含两个参数COEFF0:起始波长的log10对数,COEFF1:每个波长间隔的log10对数步长。比如这两个分别是3.5682和0.0001,第一个流量对应的波长就为10**3.5682,第二个流量对应的波长为10**(3.5682+0.0001),后面依次以这个步长计算波长。如下面两个图:

image-20211008085454019

image-20211008085402471

图像fits文件

天文图像主要用的是sdss发布的数据,其中一个区域的图像包含ugriz 5个波段的1图像(.fits.bz2)、合成伪彩图(.jpg)、星表(.fits),星表是标记出此图像中的所有天体在图像中的位置和其信息。

读取方法与前面一样。

打开一个g波段的图:

image-20211008090448711

上图中,hdu[0] 里面是图像矩阵,下图是画出来的图像,这只是单个波段,画出来不是彩色。

天体的赤经赤伟转成图像中的像素坐标方法:

1
2
3
from astropy.wcs import WCS
W = WCS(objid+'-r.fits.bz2') # 读取的不是星表,而是一个波段的图
x1, y1 = W.all_world2pix(float(ra1), float(dec1), 1)

参考链接:

https://hebl.china-vo.org/w/19387213

LAMOST星体光谱FITS文件解析与信息提取,《电脑编程技巧与维护》2019年 第8期(http://www.cqvip.com/QK/98258X/201908/7100043482.html)

https://hebl.china-vo.org/w/19884118