You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建含原FITS表头的新文件时遇截断错误,求解决方案

FITS文件处理时的截断警告问题排查与解决

我编写了一段FITS文件数据清洗代码,目标是缩减原文件中WAVE和FLUX列的维度,生成保留原表头但包含新WAVE、FLUX列的FITS文件。运行代码时触发以下警告:

WARNING: File may have been truncated: actual file length (2315520) is smaller than the expected size (1650971016000) [astropy.io.fits.file]
WARNING:astropy:File may have been truncated: actual file length (2315520) is smaller than the expected size (1650971016000)

原代码如下:

import os
import matplotlib.pyplot as plt
from astropy.io import fits
from astropy.table import Table
import numpy as np

#Reading a file and its basic features and plot it!
filename = '/home/marziefaraji/Documents/data_optic/extest/ADP.2020-06- 10T16_42_09.348.fits'

data = fits.open(filename)
data1 = Table.read(data, hdu=1)
wave = data1['WAVE'][0]
flux = data1['FLUX'][0]

plt.plot(wave, flux, label='Original Data')
plt.xlabel('Wavelength')
plt.ylabel('Flux')
plt.title('Select Points')
plt.grid(True)

#Use plt.ginput() to select points
print("Select points on the plot. Press Enter when done.")
points = plt.ginput(-1, -1)

#Close the plot window
plt.close()

#Print the selected points
print("Selected points:")
for point in points:
    print(f"X: {point[0]}, Y: {point[1]}")

#Extract the x and y coordinates of the selected points
wave_selected = [point[0] for point in points]
flux_selected = [point[1] for point in points]

#Remove the data between the selected points
wave_filtered = []
flux_filtered = []

for x, y in zip(wave, flux):
    if x < wave_selected[0] or x > wave_selected[1]:
        wave_filtered.append(x)
        flux_filtered.append(y)

#wave_filtered = np.array(wave_filtered)
#flux_filtered = np.array(flux_filtered)

#Plot the new filtered data
plt.plot(wave_filtered, flux_filtered, 'r-', label='Filtered Data')
plt.xlabel('Wavelength')
plt.ylabel('Flux')
plt.title('Filtered Data')
plt.grid(True)
plt.legend()
plt.show()
#Close the plot window
plt.close()

#Create a new FITS file with the filtered data
new_filename = os.path.splitext(filename)[0] + '_new.fits'

#Create a new primary HDU with the filtered data
primary_hdu = fits.PrimaryHDU()

#Copy the header from the original file to the new primary HDU
primary_hdu.header = data[0].header

#Create a new BinTable HDU with the filtered wave and flux columns

col1_wave = np.array(wave_filtered)
col2_flux = np.array(flux_filtered)

columns = fits.ColDefs([fits.Column(name='WAVE', format='D', array=col1_wave), 
fits.Column(name='FLUX', format='D', array=col2_flux)])

filtered_hdu = fits.BinTableHDU.from_columns(columns)

#Copy the header from the original BinTable HDU to the new BinTable HDU
filtered_hdu.header = data[1].header

#Create a new HDU list with the primary and filtered HDUs
hdul = fits.HDUList([primary_hdu, filtered_hdu])
hdul.writeto(new_filename, overwrite=True)
#Save the new FITS file
print(f"New FITS file '{new_filename}' created.")

问题原因

警告的核心是直接覆盖新BinTable HDU的表头时,保留了原文件中描述数据尺寸的关键字(如NAXIS1、NAXIS2),这些关键字与新数据的实际尺寸不匹配。astropy读取时会根据这些关键字计算预期文件大小,与实际文件大小对比后触发截断警告。

解决方法

1. 替换表头覆盖方式为表头合并

不要直接赋值原表头,改用update方法合并表头,让astropy自动生成新数据对应的尺寸关键字:

# 替换原代码中的 filtered_hdu.header = data[1].header
# 先复制原表头并移除尺寸相关关键字
original_header = data[1].header.copy()
for key in ['NAXIS1', 'NAXIS2', 'PCOUNT', 'GCOUNT']:
    if key in original_header:
        del original_header[key]
# 更新新HDU的表头
filtered_hdu.header.update(original_header)

2. 验证列格式一致性

检查原文件中WAVE和FLUX列的格式,确保新列的format参数与原文件一致。可以通过以下代码查看原列格式:

print(data[1].columns)

如果原列格式不是D(双精度浮点数),需要调整fits.Column的format参数。

3. 完整修正后的关键代码片段

#Create a new BinTable HDU with the filtered wave and flux columns
col1_wave = np.array(wave_filtered)
col2_flux = np.array(flux_filtered)

columns = fits.ColDefs([fits.Column(name='WAVE', format='D', array=col1_wave), 
fits.Column(name='FLUX', format='D', array=col2_flux)])

filtered_hdu = fits.BinTableHDU.from_columns(columns)

# 替换表头覆盖逻辑,保留原表头的非尺寸关键字
original_header = data[1].header.copy()
for key in ['NAXIS1', 'NAXIS2', 'PCOUNT', 'GCOUNT']:
    if key in original_header:
        del original_header[key]
filtered_hdu.header.update(original_header)

内容的提问来源于stack exchange,提问作者mari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:51:09