通过PyFITS / AstroPy在FITS图像中的笛卡尔投影问题

7

我已经仔细查看了很多资料,但仍未找到解决此问题的方法。

我使用matplotlib生成矩形的FITS图像,并使用AstroPy(或PyFITS)为它们应用WCS坐标。我的图像以银河系纬度和经度表示,因此适用于我的地图的头关键字应该是GLON-CARGLAT-CAR(用于笛卡尔投影)。我查看了其他在SAO DS9中使用相同地图投影方式的其他地图,并且这些坐标非常准确…与预期的完全正交。可以在此处找到FITS标准投影。

但是当我生成自己的地图时,坐标不完全符合笛卡尔坐标系。以下是我的地图(左侧)与大致相同区域的参考地图(右侧)的并排对比图。两者都列出了GLON-CARGLAT-CAR,但是当在SAO DS9中查看时,我的坐标轴出现了问题(需要注意的是,坐标网格是SAO DS9基于FITS头文件中的数据生成的,至少存储在FITS文件中某个位置):

(左)我的地图,(右)参考地图。标题关键字相同,都是笛卡尔坐标系

这非常困扰,因为如果投影错误,则坐标赋值算法将向每个像素分配错误的坐标。

有人遇到过这种情况吗,或者知道可能的问题原因?我尝试应用其他投影方式(仅为了查看它们在SAO DS9中的表现),它们表现得很好……但是我的笛卡尔和墨卡托投影没有正确显示正交网格。

我不认为这是AstroPy的bug,但我找不到任何其他原因……除非我的头文件中的参数格式不正确,但我仍然不明白它如何引起我所遇到的问题。或者您建议使用其他工具吗? (我查看了matplotlib basemap,但在我的计算机上无法使用它)。

以下是我的头代码:

 from __future__ import division
 import numpy as np
 from astropy.io import fits as pyfits # or use 'import pyfits, same thing'

 #(lots of code in between: defining variables and simple calculations...
 #probably not relevant)

 header['BSCALE'] = (1.00000, 'REAL = TAPE*BSCALE + BZERO')
 header['BZERO'] = (0.0)
 header['BUNIT'] = ('mag ', 'UNIT OF INTENSITY')
 header['BLANK'] = (-100.00, 'BLANK VALUE')
 header['CRVAL1'] = (glon_center, 'REF VALUE POINT DEGR')   #FIRST COORDINATE OF THE CENTER
 header['CRPIX1'] = (center_x+0.5, 'REF POINT PIXEL LOCATION') ## REFERENCE X PIXEL
 header['CTYPE1'] = ('GLON-CAR', 'COORD TYPE : VALUE IS DEGR')
 header['CDELT1'] = (-glon_length/x_length, 'COORD VALUE INCREMENT WITH COUNT DGR')   ### degrees per pixel
 header['CROTA1'] = (0, 'CCW ROTATION in DGR')            
 header['CRVAL2'] = (glat_center, 'REF VALUE POINT DEGR') #Y COORDINATE OF THE CENTER
 header['CRPIX2'] = (center_y+0.5, 'REF POINT PIXEL LOCATION') #Y REFERENCE PIXEL 
 header['CTYPE2'] = ('GLAT-CAR', 'COORD TYPE: VALUE IS DEGR')   # WAS CAR OR TAN
 header['CDELT2'] = (glat_length/y_length, 'COORD VALUE INCREMENT WITH COUNT DGR') #degrees per pixel  
 header['CROTA2'] = (rotation, 'CCW ROTATION IN DEGR')                               #NEGATIVE ROTATES CCW around origin (bottom left). 
 header['DATAMIN'] = (data_min, 'Minimum data value in the file') 
 header['DATAMAX'] = (data_max, 'Maximum data value in the file')
 header['TELESCOP'] = ("Produced from 2MASS")

 pyfits.update(filename, map_data, header)

感谢您能提供的任何帮助。

1个回答

9
在现代定义的(Calabretta等人提出的)-CAR投影中,只有当CRVAL2设为零时,GLON-CAR/GLAT-CAR投影才产生一个直角网格。如果CRVAL2不为零,则网格会呈弯曲形状(这与Astropy无关)。你可以通过调整CRVAL2CRPIX2使CRVAL2为零来尝试修复此问题。这有帮助吗?
为了澄清我的意思,请在您上面的代码之后,并在写出文件之前尝试:
header['CRPIX2'] -= header['CRVAL2'] / header['CDELT2']
header['CRVAL2'] = 0.

有运气了吗?

如果您查看所查看的 'reference' 文件的头文件,您会发现那里的 CRVAL2 值为零。仅仅是为了明确,CRVAL2 非零并没有什么问题,但网格就不再是长方形的了。


1
就是这样!!!哇,非常感谢……我自己永远不会发现那个解决方案。对于未来遇到此问题的任何人,只需注意一下……由于这意味着将参考坐标设置为原点(0,0),所以最后一步就是确定原点的像素值(CRPIX1和CRPIX2)。因此,根据地图的坐标,您的一个或两个参考像素可能是负值。我必须稍微修改astrofrog的代码才能使其适用于我(特别是,我必须乘以倒数——即1/header['CDELT1']——以得到正确的值)。 - Teachey
1
@Teachey - 啊,是的,我把它搞错了 - 我来修复! - astrofrog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接