【问题标题】:Coordinate conversion problem of a FITS fileFITS文件的坐标转换问题
【发布时间】:2023-04-03 21:30:01
【问题描述】:

我已经在 python 中加载并绘制了一个 FITS 文件。 在上一篇文章的帮助下,我设法将轴从像素转换为天体坐标。但我无法正确地在毫秒(mas)内得到它们。 代码如下

import numpy as np
import matplotlib.pyplot as plt
import astropy.units as u
from astropy.wcs import WCS
from astropy.io import fits
from astropy.utils.data import get_pkg_data_filename

filename = get_pkg_data_filename('hallo.fits')


hdu = fits.open(filename)[0]
wcs = WCS(hdu.header).celestial
wcs.wcs.crval = [0,0]

plt.subplot(projection=wcs) 
plt.imshow(hdu.data[0][0], origin='lower') 
plt.xlim(200,800)
plt.ylim(200,800)
plt.xlabel('Relative R.A ()')
plt.ylabel('Relative Dec ()')
plt.colorbar()

输出看起来像

y标签被剪掉了,我不知道。

正如另一篇文章中显示的那样,人们可以使用

wcs.wcs.ctype = [ 'XOFFSET' , 'YOFFSET' ]

将它切换到毫秒,我得到

但比例不正确!。 例如,0deg00min00.02sec 应该是 20 mas 而不是 0.000002! 我错过了什么吗?

【问题讨论】:

  • 您可能会通过包含 plt.tight_layout() 行来解决 y-label 被切断的问题。
  • 没错,添加 fig = plt.figure(figsize=(add your size here)) 也有帮助。

标签: python-3.x astropy fits


【解决方案1】:

看起来像光谱索引图。好的! 我认为问题可能在于 FITS 隐含地使用度数来表示 CDELT 等值。并且应该为情节明确地将它们转换为 mas 。 最直接的方法是将 CDELT 值乘以 3.6e6 以将度数转换为 mas。 但是,如果您想在某些时候转换为不同的单位,有一种更通用的方法可能会很有用:

import astropy.units as u
w.wcs.cdelt = (w.wcs.cdelt * u.deg).to(u.mas)

所以它基本上首先说 CDELT 的单位是度,然后将它们转换为 mas。

整个工作流程是这样的:

def make_transform(f):
    '''use already read-in FITS file object f to build pixel-to-mas transformation'''
    print("Making a transformation out of a FITS header")

    w = WCS(f[0].header)
    w = w.celestial
    
    w.wcs.crval = [0, 0]
    w.wcs.ctype = [ 'XOFFSET' , 'YOFFSET' ]
    w.wcs.cunit = ['mas' , 'mas']
    w.wcs.cdelt = (w.wcs.cdelt * u.deg).to(u.mas)
    print(w.world_axis_units)
    return w

def read_fits(file):
    '''read fits file into object'''
    try:
        res =  fits.open(file)
        return res
    except:
        return None

def start_plot(i,df=None, w=None, xlim = [None, None], ylim=[None, None]):
    '''starts a plot and returns fig,ax .
    xlim, ylim - axes limits in mas
    '''
       
    # make a transformation
    # Using a dataframe
    if df is not None:
        w = make_transform_df(df)         
    # using a header    
    if w is not None:
        pass
    # not making but using one from the arg list
    else:
        w = make_transform(i)

#    print('In start_plot using the following transformation:\n {}'.format(w))


    fig = plt.figure()
    
    if w.naxis == 4:
        ax = plt.subplot(projection = w, slices = ('x', 'y', 0 ,0 ))
    elif w.naxis == 2:
        ax = plt.subplot(projection = w)
        
    
    # convert xlim, ylim to coordinates of BLC and TRC, perform transformation, then return back to xlim, ylim in pixels
    if any(xlim) and any(ylim):
        xlim_pix, ylim_pix = limits_mas2pix(xlim, ylim, w)
        ax.set_xlim(xlim_pix)
        ax.set_ylim(ylim_pix)
        
    
    fig.add_axes(ax)  # note that the axes have to be explicitly added to the figure
    return fig, ax 


rm = read_fits(file)
wr = make_transform(rm)
fig, ax = start_plot(RM, w=wr, xlim = xlim, ylim = ylim)

然后只需使用 imshow 或轮廓或其他东西绘制到轴 ax 上。 当然,可以减少这段代码以满足您的特定需求。

【讨论】:

  • 谢谢米哈伊尔。我已经解决了我的问题,一位朋友建议添加 lon = ax.coords[0] lat = ax.coords[1]。现在它适用于最新的 python 版本。
猜你喜欢
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多