вызвал определенную функцию: операция ввода-вывода в закрытом файле - PullRequest
0 голосов
/ 04 августа 2020

Я определил функцию для исправления и открытия файла соответствия в списке. Затем вызовите его дважды, чтобы изображение полностью совпадало. Но когда я использовал параметры вызываемой функции для построения графика, это показывает, что операция ввода-вывода в закрытом файле: «ValueError: операция ввода-вывода в закрытом файле». Не знаю, почему это происходит. Большое вам спасибо.

Ниже приведен код определенной функции

import numpy as np
import matplotlib.pyplot as plt
import applpy
from astropy.io import fits
from astropy.wcs import WCS
from astropy.wcs import FITSFixedWarning
import warnings

warnings.filterwarnings("ignore", category=FITSFixedWarning)


#### define the function to fix the fitsheader and get the head info.
def fix_fitshead(filelis):
    with fits.open(filelis.replace('\n', ''), mode="readonly") as hdu:
        da = hdu[0].data[:,:]
        he = hdu[0].header
            
    if he["NAXIS"] ==4:
        he["NAXIS"] =2
        for k in ["NAXIS3", "NAXIS4", 
                  "CTYPE3", "CRVAL3", "CDELT3", "CROTA3", "CRPIX3", 
                  "CTYPE4", "CRVAL4", "CDELT4", "CROTA4", "CRPIX4" ]:
            if k in list(he.keys()):
                he.remove(k)
        hdu = fits.PrimaryHDU(da, he)
        print('WCS=',WCS(he))
    elif he["NAXIS"] ==3:
        he["NAXIS"] =1 
        for k in ["NAXIS3","CTYPE3", "CRVAL3", "CRPIX3","CUNIT3", "LBOUND3"]: 
            if k in list(he.keys()):
                he.remove(k)
            if "CDELT3" in h3:
                k1 = "CDELT3"
            elif "CD3_3" in h3:
                k1 = "CD3_3"
                he.remove(k1)
        hdu = fits.PrimaryHDU(da, he)
    else:
        hdu = hdu[0]
    maxvalue = np.nanmax(da)
     
    c = WCS(he).wcs_pix2world([[he["NAXIS1"]/2,he["NAXIS2"]/2]], 1)
    coord = SkyCoord(ra=c[0][0]*u.deg, dec=c[0][1]*u.deg)
    
    if "LINE" in he:
        spec = he["LINE"]
    elif 'MOLECULE' in he:
        spec = he['MOLECULE']
    elif "INSTRUME"in he:
        spec = he['INSTRUME']
        print(he["OBJECT"]) 
#        print(maxvalue) 
        
#    PRODID  = 'reduced-850um'   
    return maxvalue, spec, da, he, hdu, coord


##The following code is plot the overlay picture by calling the defined function.

file_gray = '/Users/hjma/Desktop/smoothdata/progress/13co_fits.list'
file_cont  = '/Users/hjma/Desktop/smoothdata/progress/hcn10_fits.list'

with open(file_gray,'r') as f_gray:
    gray_list = [row_gray.rstrip('\n') for row_gray in f_gray]
with open(file_cont,'r') as f_cont:
    cont_list = [row_cont.rstrip('\n') for row_cont in f_cont]

for filegray in gray_list:
#    print('filegray=',filegray)
    
    #call the defined function
    maxvalue1, spec1, d1, he1, hdu_gray, coord1 = fix_fitshead(filegray)

    for filecont in cont_list:
#        print('filecont=', filecont)

        #call the defined function       
        maxvalue2, spec2, d2, he2, hdu_cont, coord2 = fix_fitshead(filecont)
        print('d2=',d2)
        
        
        fig = plt.figure()
        fig.set_figwidth(4); fig.set_figheight(4)
            
        ff = aplpy.FITSFigure(hdu_gray, figure=fig)
        ff.show_colorscale(cmap="Blues")
        ff.show_contour(hdu_cont, colors="red")
        
        plt.plot([0], label="HCN 1-0", color="r")
        plt.legend()
        plt.tight_layout()
        
        plt.close()
        break`

Я получил ошибку:

---> 26 ff = aplpy.FITSFigure ( hdu_gray, figure = fig) .... ValueError: операция ввода-вывода для закрытого файла

1 Ответ

0 голосов
/ 11 августа 2020

Выше я добавил несколько общих комментариев по проблемам с вашим кодом, которые вы, возможно, захотите решить. Я бы предложил вам переписать ваш код, за исключением того, что я не уверен на 100%, что это означает для достижения sh. Похоже, что, помимо прочего, вы хотите, чтобы он брал 2D-срезы 3D или 4D массивов, но, как я отмечал выше, на самом деле это не достигает этой цели.

В любом случае причина вашей ошибки конкретно в случае, когда данные уже 2D, в вашем операторе if / elif / else у вас есть:

    if he["NAXIS"] == 4:
        ...
        hdu = fits.PrimaryHDU(da, he)
        print('WCS=',WCS(he))
    elif he["NAXIS"] == 3:
        ...
        hdu = fits.PrimaryHDU(da, he)
    else:
        hdu = hdu[0]

В первых двух случаях вы читаете данные из файла перед закрытием файла (da = hdu[0].data[:,:] ) и создал из него новый объект HDU. Однако в последнем случае вы этого не сделали, а просто передали исходный объект HDU из закрытого файла (hdu = hdu[0]). Поскольку файл, из которого он сделан, закрыт, данные в этом HDU больше не могут быть готовы, поэтому вы получите «операцию ввода-вывода для закрытого файла», когда вы передадите его в aplpy.FITSFigure, и он попытается прочитать данные HDU.

Один из способов обойти это - изменить последнюю строку на hdu = fits.PrimaryHDU(da, he), как и в других случаях, чтобы создать новый HDU из уже загруженных данных.

Лучший способ, который в соответствии с вашим комментарием, я думаю, вы, возможно, нашли, это рефакторинг вашего кода, чтобы вместо передачи fix_fitshead имени файла передать ему уже открытый объект HDUList и использовать его как:

with fits.open(filename) as hdul:
    maxvalue1, spec1, d1, he1, hdu_gray, coord1 = fix_fitshead(hdul)
    ...

и не закрывайте файл, пока не закончите его использовать. В целом это более гибкий подход, поскольку он также позволяет вам использовать ваш код для файлов FITS, которые не были открыты напрямую из файлов на диске (например, для написания тестов).

...