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

如何将含Galactocentric系SkyCoord的Astropy QTable保存为FITS文件?

问题:Galactocentric坐标系SkyCoord写入FITS QTable时出错

创建Galactocentric坐标系的SkyCoord对象:

c_end = SkyCoord(
    x=xf,
    y=yf,
    z=zf,
    v_x=vxf,
    v_y=vyf,
    v_z=vzf,
    frame='galactocentric'
)

尝试将其存入Astropy QTable并写入FITS文件:

tab = QTable([c_end, ...], names = ['skycoord', ...])

tab.write('name.fits', format = 'fits')

触发以下错误:

yaml.representer.RepresenterError: ('cannot represent an object', <ICRS Coordinate: (ra, dec) in deg
(266.4051, -28.936175)>)

这个ICRS坐标是银心位置,即使转换为ICRS系后保存仍报错。可复现的最小示例代码:

from astropy.coordinates import SkyCoord
from astropy.table import QTable
import astropy.units as u

xf, yf, zf = 8.3, 0.0, 0.02
vxf, vyf, vzf = -11.1, 232.24, 7.25

c_end = SkyCoord(
    x=xf*u.kpc,
    y=yf*u.kpc,
    z=zf*u.kpc,
    v_x=vxf*u.km/u.s,
    v_y=vyf*u.km/u.s,
    v_z=vzf*u.km/u.s,
    frame='galactocentric'
)

tab = QTable([[c_end]], names=['skycoord'])

try:
    tab.write('name_fail.fits', format='fits', overwrite=True)
    print("Wrote FITS successfully.")
except Exception as e:
    print("Failed to write FITS:", e)

运行后输出:

Failed to write FITS: ('cannot represent an object', <ICRS Coordinate: (ra, dec) in deg
(266.4051, -28.936175)>)

错误原因

Galactocentric坐标系的SkyCoord对象内部包含银心的ICRS坐标参考点(galcen_coord属性),当QTable写入FITS时,会尝试用YAML序列化列的元数据,而这个ICRS坐标对象无法被YAML正常序列化,从而触发错误。

解决方法

方法1:拆分SkyCoord为单独的物理量列

将SkyCoord的位置和速度分量拆分为单独的带单位列存入QTable,避免直接存储SkyCoord对象:

from astropy.coordinates import SkyCoord
from astropy.table import QTable
import astropy.units as u

xf, yf, zf = 8.3, 0.0, 0.02
vxf, vyf, vzf = -11.1, 232.24, 7.25

c_end = SkyCoord(
    x=xf*u.kpc,
    y=yf*u.kpc,
    z=zf*u.kpc,
    v_x=vxf*u.km/u.s,
    v_y=vyf*u.km/u.s,
    v_z=vzf*u.km/u.s,
    frame='galactocentric'
)

# 拆分分量为单独列
tab = QTable({
    'x': c_end.x,
    'y': c_end.y,
    'z': c_end.z,
    'v_x': c_end.v_x,
    'v_y': c_end.v_y,
    'v_z': c_end.v_z
})

tab.write('name_success.fits', format='fits', overwrite=True)
print("Wrote FITS successfully.")

后续读取时可重新组合为SkyCoord对象:

tab_read = QTable.read('name_success.fits')
c_read = SkyCoord(
    x=tab_read['x'],
    y=tab_read['y'],
    z=tab_read['z'],
    v_x=tab_read['v_x'],
    v_y=tab_read['v_y'],
    v_z=tab_read['v_z'],
    frame='galactocentric'
)

方法2:使用serialize_method='data'参数跳过元数据序列化

在写入FITS时,指定serialize_method='data',让Astropy只序列化数据部分,不处理元数据中的复杂对象:

from astropy.coordinates import SkyCoord
from astropy.table import QTable
import astropy.units as u

xf, yf, zf = 8.3, 0.0, 0.02
vxf, vyf, vzf = -11.1, 232.24, 7.25

c_end = SkyCoord(
    x=xf*u.kpc,
    y=yf*u.kpc,
    z=zf*u.kpc,
    v_x=vxf*u.km/u.s,
    v_y=vyf*u.km/u.s,
    v_z=vzf*u.km/u.s,
    frame='galactocentric'
)

tab = QTable([[c_end]], names=['skycoord'])

try:
    # 添加serialize_method参数
    tab.write('name_success.fits', format='fits', overwrite=True, serialize_method='data')
    print("Wrote FITS successfully.")
except Exception as e:
    print("Failed to write FITS:", e)

注意:此方法写入的FITS文件,后续读取时SkyCoord的框架元数据(如galcen_coord)会使用默认值,而非原始对象的设置。如果需要保留精确的框架参数,建议使用方法1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 12:43:10