Python 使用astropy.fits和numpy对SWIFT fits图像应用符合校正
这个问题可能有点专业,但希望有人能帮上忙。我通常使用IDL,但对于开发管道,我希望使用python来提高运行时间 我的fits文件处理设置如下所示:Python 使用astropy.fits和numpy对SWIFT fits图像应用符合校正,python,numpy,idl-programming-language,astropy,Python,Numpy,Idl Programming Language,Astropy,这个问题可能有点专业,但希望有人能帮上忙。我通常使用IDL,但对于开发管道,我希望使用python来提高运行时间 我的fits文件处理设置如下所示: import numpy as numpy from astropy.io import fits #Directory: /Users/UCL_Astronomy/Documents/UCL/PHASG199/M33_UVOT_sum/UVOTIMSUM/M33_sum_epoch1_um2_norm.img with fits.open('.
import numpy as numpy
from astropy.io import fits
#Directory: /Users/UCL_Astronomy/Documents/UCL/PHASG199/M33_UVOT_sum/UVOTIMSUM/M33_sum_epoch1_um2_norm.img
with fits.open('...') as ima_norm_um2:
#Open UVOTIMSUM file once and close it after extracting the relevant values:
ima_norm_um2_hdr = ima_norm_um2[0].header
ima_norm_um2_data = ima_norm_um2[0].data
#Individual dimensions for number of x pixels and number of y pixels:
nxpix_um2_ext1 = ima_norm_um2_hdr['NAXIS1']
nypix_um2_ext1 = ima_norm_um2_hdr['NAXIS2']
#Compute the size of the images (you can also do this manually rather than calling these keywords from the header):
#Call the header and data from the UVOTIMSUM file with the relevant keyword extensions:
corrfact_um2_ext1 = numpy.zeros((ima_norm_um2_hdr['NAXIS2'], ima_norm_um2_hdr['NAXIS1']))
coincorr_um2_ext1 = numpy.zeros((ima_norm_um2_hdr['NAXIS2'], ima_norm_um2_hdr['NAXIS1']))
#Check that the dimensions are all the same:
print(corrfact_um2_ext1.shape)
print(coincorr_um2_ext1.shape)
print(ima_norm_um2_data.shape)
# Make a new image file to save the correction factors:
hdu_corrfact = fits.PrimaryHDU(corrfact_um2_ext1, header=ima_norm_um2_hdr)
fits.HDUList([hdu_corrfact]).writeto('.../M33_sum_epoch1_um2_corrfact.img')
# Make a new image file to save the corrected image to:
hdu_coincorr = fits.PrimaryHDU(coincorr_um2_ext1, header=ima_norm_um2_hdr)
fits.HDUList([hdu_coincorr]).writeto('.../M33_sum_epoch1_um2_coincorr.img')
我希望随后应用以下更正:
# Define the variables from Poole et al. (2008) "Photometric calibration of the Swift ultraviolet/optical telescope":
alpha = 0.9842000
ft = 0.0110329
a1 = 0.0658568
a2 = -0.0907142
a3 = 0.0285951
a4 = 0.0308063
for i in range(nxpix_um2_ext1 - 1): #do begin
for j in range(nypix_um2_ext1 - 1): #do begin
if (numpy.less_equal(i, 4) | numpy.greater_equal(i, nxpix_um2_ext1-4) | numpy.less_equal(j, 4) | numpy.greater_equal(j, nxpix_um2_ext1-4)): #then begin
#UVM2
corrfact_um2_ext1[i,j] == 0
coincorr_um2_ext1[i,j] == 0
else:
xpixmin = i-4
xpixmax = i+4
ypixmin = j-4
ypixmax = j+4
#UVM2
ima_UVM2sum = total(ima_norm_um2[xpixmin:xpixmax,ypixmin:ypixmax])
xvec_UVM2 = ft*ima_UVM2sum
fxvec_UVM2 = 1 + (a1*xvec_UVM2) + (a2*xvec_UVM2*xvec_UVM2) + (a3*xvec_UVM2*xvec_UVM2*xvec_UVM2) + (a4*xvec_UVM2*xvec_UVM2*xvec_UVM2*xvec_UVM2)
Ctheory_UVM2 = - alog(1-(alpha*ima_UVM2sum*ft))/(alpha*ft)
corrfact_um2_ext1[i,j] = Ctheory_UVM2*(fxvec_UVM2/ima_UVM2sum)
coincorr_um2_ext1[i,j] = corrfact_um2_ext1[i,j]*ima_sk_um2[i,j]
xvec_UVM2 = ft*ima_UVM2sum_valid
fxvec_UVM2 = 1 + (a1*xvec_UVM2) + (a2*xvec_UVM2**2) + (a3*xvec_UVM2**3) + (a4*xvec_UVM2**4)
Ctheory_UVM2 = - np.alog(1-(alpha*ima_UVM2sum_valid*ft))/(alpha*ft)
上面的代码片段就是混乱的地方,因为我混合了IDL语法和python语法。我只是不知道如何将IDL的某些方面转换为python。例如,ima\u UVM2sum=total(ima\u norm\u um2[xpixmin:xpixmax,ypixmin:ypixmax])
我不太确定如何处理
我会说,我还遗漏了它将更新校正因子和符合校正图像文件的部分。如果有人能耐心仔细检查一下,并提出我需要的必要修改,那就太好了
原始的标准化图像可以在这里下载:numpy的一个非常重要的事情是它以元素为基础执行每个数学或比较函数。因此,您可能不需要在数组中循环 因此,可以从使用求和过滤器对图像进行卷积开始。这可以通过
astropy.卷积.卷积
或
我不确定你想要什么,但我想你想要一个9x9和滤波器,它可以通过
from scipy.ndimage.filters import uniform_filter
ima_UVM2sum = uniform_filter(ima_norm_um2_data, size=9)
由于要丢弃边界处的任何像素(4像素),您只需将其切片即可:
ima_UVM2sum_valid = ima_UVM2sum[4:-4,4:-4]
这将忽略第一行和最后4行以及第一列和最后4列(最后一列是通过将停止值设置为负值来实现的)
现在,您要计算更正:
# Define the variables from Poole et al. (2008) "Photometric calibration of the Swift ultraviolet/optical telescope":
alpha = 0.9842000
ft = 0.0110329
a1 = 0.0658568
a2 = -0.0907142
a3 = 0.0285951
a4 = 0.0308063
for i in range(nxpix_um2_ext1 - 1): #do begin
for j in range(nypix_um2_ext1 - 1): #do begin
if (numpy.less_equal(i, 4) | numpy.greater_equal(i, nxpix_um2_ext1-4) | numpy.less_equal(j, 4) | numpy.greater_equal(j, nxpix_um2_ext1-4)): #then begin
#UVM2
corrfact_um2_ext1[i,j] == 0
coincorr_um2_ext1[i,j] == 0
else:
xpixmin = i-4
xpixmax = i+4
ypixmin = j-4
ypixmax = j+4
#UVM2
ima_UVM2sum = total(ima_norm_um2[xpixmin:xpixmax,ypixmin:ypixmax])
xvec_UVM2 = ft*ima_UVM2sum
fxvec_UVM2 = 1 + (a1*xvec_UVM2) + (a2*xvec_UVM2*xvec_UVM2) + (a3*xvec_UVM2*xvec_UVM2*xvec_UVM2) + (a4*xvec_UVM2*xvec_UVM2*xvec_UVM2*xvec_UVM2)
Ctheory_UVM2 = - alog(1-(alpha*ima_UVM2sum*ft))/(alpha*ft)
corrfact_um2_ext1[i,j] = Ctheory_UVM2*(fxvec_UVM2/ima_UVM2sum)
coincorr_um2_ext1[i,j] = corrfact_um2_ext1[i,j]*ima_sk_um2[i,j]
xvec_UVM2 = ft*ima_UVM2sum_valid
fxvec_UVM2 = 1 + (a1*xvec_UVM2) + (a2*xvec_UVM2**2) + (a3*xvec_UVM2**3) + (a4*xvec_UVM2**4)
Ctheory_UVM2 = - np.alog(1-(alpha*ima_UVM2sum_valid*ft))/(alpha*ft)
这些都是数组,所以您仍然不需要循环
但是,你要填充你的两张图片。请小心,因为校正较小(我们输入了第一行和最后一行/列),所以您必须在校正图像中获取相同的区域:
corrfact_um2_ext1[4:-4,4:-4] = Ctheory_UVM2*(fxvec_UVM2/ima_UVM2sum_valid)
coincorr_um2_ext1[4:-4,4:-4] = corrfact_um2_ext1[4:-4,4:-4] *ima_sk_um2
仍然没有使用numpys
数学函数的循环。这意味着它的速度要快得多(快得多!),并且做得也一样
可能我忘记了一些切片,这将产生一个不可广播的错误
,如果是,请报告
关于循环,请注意:Python的第一个轴是FITS中的第二个轴,第二个轴是FITS中的第一个轴。因此,如果需要在轴上循环,请记住这一点,这样就不会出现索引器或意外结果。嗨,Michael。非常感谢你冗长的答复。非常感谢。只是一个快速查询,行xvec_UVM2=ftima_UVM2sum实际上应该是xvec_UVM2=ftima_UVM2sum_有效吗?(附言会把这个写进我的剧本里,看看它是怎么回事。)是的,当然!当我写答案时,我忘了将第一行和最后一行和最后一列切分,只是后来才把它包括进去。因此,每个后续的ima_UVM2sum
都应该是ima_UVM2sum\u有效的。请尝试从scipy.ndimage.filters导入uniform_filter
,然后通过uniform_filter
替换scipy.ndimage.filters.uniform_filter
,您已经将这些校正图像写入磁盘(在writeto
期间),您希望他们在哪里更新?或者我遗漏了一个步骤?啊,对不起,是的,在计算之后,您必须将所有写入到相关代码中。:-)