创建含原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
相关产品推荐
相关产品推荐

