如何将天文光谱ASCII文件转换为FITS文件?
问题解决思路
核心问题分析
你当前的Astropy代码只是将ASCII文件的二维数据直接写入FITS,但没有定义波长的色散信息——FITS光谱需要通过头文件关键字或单独扩展来关联像素位置与实际波长,否则读取工具无法识别第一列的波长数据。IRAF的rspectex任务同样需要明确指定哪一列对应波长,否则会默认按像素索引处理。
解决方法
方法1:通过FITS头关键字定义线性色散(推荐)
如果你的波长是线性分布的,直接在FITS头中添加色散关键字,让工具自动计算每个像素对应的波长:
import numpy as np from astropy.io import fits # 读取ASCII数据,拆分波长和通量列 data = np.loadtxt('spectrum.ascii') wavelength = data[:, 0] flux = data[:, 1] # 构建包含色散信息的头文件 hdr = fits.Header() hdr['SIMPLE'] = True hdr['OBJECT'] = 'object' hdr['COMMENT'] = 'comment' # 色散核心关键字 hdr['CRVAL1'] = wavelength[0] # 第1个像素对应的波长值 hdr['CRPIX1'] = 1.0 # 参考像素位置(通常设为1) hdr['CDELT1'] = wavelength[1] - wavelength[0] # 波长步长(线性分布时有效) hdr['CUNIT1'] = 'Angstrom' # 波长单位(根据实际情况修改) # 将通量数据写入PrimaryHDU,关联头文件 hdu = fits.PrimaryHDU(data=flux, header=hdr) # 覆盖已有文件需加overwrite=True hdu.writeto('spectrum.fits', overwrite=True)
方法2:用多扩展FITS存储波长(适合非线性波长)
如果波长是非线性分布,直接将波长作为单独的扩展写入FITS,避免色散计算误差:
import numpy as np from astropy.io import fits data = np.loadtxt('spectrum.ascii') wavelength = data[:, 0] flux = data[:, 1] # 主扩展存储通量数据 primary_hdu = fits.PrimaryHDU(data=flux) primary_hdu.header['OBJECT'] = 'object' primary_hdu.header['COMMENT'] = 'comment' # 创建单独的波长扩展 wavelength_hdu = fits.ImageHDU(data=wavelength, name='WAVELENGTH') wavelength_hdu.header['CUNIT1'] = 'Angstrom' # 组合扩展并写入文件 hdulist = fits.HDUList([primary_hdu, wavelength_hdu]) hdulist.writeto('spectrum_wavelength.fits', overwrite=True)
关于IRAF rspectex的设置
rspectex默认不会自动识别ASCII的第一列为波长,需手动指定参数:
- 设置
inputcols="1,2":明确第一列是波长,第二列是通量 - 补充
wavelength_units参数,指定波长单位(如Angstrom) - 若波长非线性,可能需要配合
dispfile或手动设置色散关键字
内容的提问来源于stack exchange,提问作者Carl
相关产品推荐
相关产品推荐

