Python 使用astropy.fits和numpy对SWIFT 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('.

这个问题可能有点专业,但希望有人能帮上忙。我通常使用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('...') 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
期间),您希望他们在哪里更新?或者我遗漏了一个步骤?啊,对不起,是的,在计算之后,您必须将所有
写入到
相关代码中。:-)