我该怎么做才能让我的程序不为 .fits 文件中不存在的 Header 抛出 KeyError?
What can I do for my program not to throw a KeyError for a Header not existing in a .fits file?
我正在制作一个程序,在计算机中搜索 .fts 和 .fits 文件,它会在其中打开文件并检索与 header 中特定关键字相对应的信息,并将文件重命名为该关键字.
我一直收到 KeyError 的问题,因为在文件中找不到我正在搜索的 header 关键字。有没有解决的办法?我希望能够搜索各种关键字并执行某些操作,即使文件中不存在该关键字。
代码如下:
from astropy.io import fits
import os
for i in os.listdir(os.getcwd()):
if i.endswith(".fits") or i.endswith(".fts"):
hdulist = fits.open(i)
DATEOBS_header = hdulist[0].header['DATE-OBS']
EXPTIME_header = int(round(hdulist[0].header['EXPTIME']))
CCDTEMP_header = int(round(hdulist[0].header['CCD-TEMP']))
XBINNING_header = hdulist[0].header['XBINNING']
FILTER_header = hdulist[0].header['FILTER']
IMAGETYP_header = hdulist[0].header['IMAGETYP']
OBJECT_header = hdulist[0].header['OBJECT']
DATEandTIME = DATEOBS_header[0:]
YEAR = DATEandTIME[0:4]
MONTH = DATEandTIME[5:7]
DAY = DATEandTIME[8:10]
#TIME = DATEOBS_header[11:]
HOUR = DATEandTIME[11:13]
MINUTE = DATEandTIME[14:16]
SECONDS = DATEandTIME[17:]
DATE = str(YEAR) + str(MONTH) + str(DAY) + 'at' + str(HOUR) + str(MINUTE) + str(SECONDS)
if IMAGETYP_header == 'Light Frame':
newname = str(OBJECT_header) + '_' + str(DATE) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'
if IMAGETYP_header == 'Dark Frame':
newname = 'Dark_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime' + '.fits'
if IMAGETYP_header == 'Flat Field':
newname = 'Flat_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'
prevname = i
os.rename(prevname, newname)
hdulist.close()
continue
else:
continue
这是我得到的错误:
Traceback (most recent call last):
File "glo1.py", line 9, in <module>
DATEOBS_header = hdulist[0].header['DATE-OBS']
File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 151, in __getitem__
card = self._cards[self._cardindex(key)]
File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 1723, in _cardindex
raise KeyError("Keyword %r not found." % keyword)
KeyError: "Keyword 'DATE-OBS' not found."
假设 hdulist[0].header
给你一个 dict
实例,你可以做类似
DATEOBS_header = hdulist[0].header.get('DATE-OBS')
如果键 'DATE-OBS'
不存在,return 会 None
。
有关详细信息,请参阅 https://docs.python.org/2/library/stdtypes.html#dict.get。
要防止这些类型的异常停止您的程序,您可以像这样捕获它们:
try:
DATEOBS_header = hdulist[0].header['DATE-OBS']
except KeyError:
DATEOBS_header = None
或者,使用字典的 .get()
方法,检查键是否存在,如果不存在则 returns 默认值,而不是引发异常。返回的默认值为 None
.
如果你这样做,你还需要设置一些合理的默认值,或者捕捉那些你正在转换值的情况(因为你不能转换 None
)。
最后,无论何时从文件中读取 - 您都应该始终假设数据是 malformed/junk 并进行一些防御性编程。在您的代码中,您假设 CCDTEMP
的返回值是一个数字,但如果文件已损坏或有空白怎么办?您的应用程序不处理这种情况。
下面是一些尝试捕获尽可能多的错误的代码:
DATEOBS_header = hdulist[0].header.get('DATE-OBS')
XBINNING_header = hdulist[0].header.get('XBINNING')
FILTER_header = hdulist[0].header.get('FILTER')
IMAGETYP_header = hdulist[0].header.get('IMAGETYP')
OBJECT_header = hdulist[0].header.get('OBJECT')
# For these two, you need to either set a default
# Here I am setting the default to 0, ------------v
EXPTIME_header = int(round(hdulist[0].header.get('EXPTIME', 0)))
# Or you need to check for a value :
ccdtemp_value = hdulist[0].header.get('CCD-TEMP')
try:
ccdtemp_value = int(round(ccdtemp_value))
except ValueError:
# This means, the value was either None (header does not exist)
# or it was something that can't be converted to a number
# since it cannot be converted to a number, we do not know
# if the value is None or something like an empty string,
# so we explicitly set the value to None
ccdtemp_value = None
CCDTEMP_header = ccdtemp_value
我正在制作一个程序,在计算机中搜索 .fts 和 .fits 文件,它会在其中打开文件并检索与 header 中特定关键字相对应的信息,并将文件重命名为该关键字.
我一直收到 KeyError 的问题,因为在文件中找不到我正在搜索的 header 关键字。有没有解决的办法?我希望能够搜索各种关键字并执行某些操作,即使文件中不存在该关键字。
代码如下:
from astropy.io import fits
import os
for i in os.listdir(os.getcwd()):
if i.endswith(".fits") or i.endswith(".fts"):
hdulist = fits.open(i)
DATEOBS_header = hdulist[0].header['DATE-OBS']
EXPTIME_header = int(round(hdulist[0].header['EXPTIME']))
CCDTEMP_header = int(round(hdulist[0].header['CCD-TEMP']))
XBINNING_header = hdulist[0].header['XBINNING']
FILTER_header = hdulist[0].header['FILTER']
IMAGETYP_header = hdulist[0].header['IMAGETYP']
OBJECT_header = hdulist[0].header['OBJECT']
DATEandTIME = DATEOBS_header[0:]
YEAR = DATEandTIME[0:4]
MONTH = DATEandTIME[5:7]
DAY = DATEandTIME[8:10]
#TIME = DATEOBS_header[11:]
HOUR = DATEandTIME[11:13]
MINUTE = DATEandTIME[14:16]
SECONDS = DATEandTIME[17:]
DATE = str(YEAR) + str(MONTH) + str(DAY) + 'at' + str(HOUR) + str(MINUTE) + str(SECONDS)
if IMAGETYP_header == 'Light Frame':
newname = str(OBJECT_header) + '_' + str(DATE) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'
if IMAGETYP_header == 'Dark Frame':
newname = 'Dark_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime' + '.fits'
if IMAGETYP_header == 'Flat Field':
newname = 'Flat_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'
prevname = i
os.rename(prevname, newname)
hdulist.close()
continue
else:
continue
这是我得到的错误:
Traceback (most recent call last):
File "glo1.py", line 9, in <module>
DATEOBS_header = hdulist[0].header['DATE-OBS']
File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 151, in __getitem__
card = self._cards[self._cardindex(key)]
File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 1723, in _cardindex
raise KeyError("Keyword %r not found." % keyword)
KeyError: "Keyword 'DATE-OBS' not found."
假设 hdulist[0].header
给你一个 dict
实例,你可以做类似
DATEOBS_header = hdulist[0].header.get('DATE-OBS')
如果键 'DATE-OBS'
不存在,return 会 None
。
有关详细信息,请参阅 https://docs.python.org/2/library/stdtypes.html#dict.get。
要防止这些类型的异常停止您的程序,您可以像这样捕获它们:
try:
DATEOBS_header = hdulist[0].header['DATE-OBS']
except KeyError:
DATEOBS_header = None
或者,使用字典的 .get()
方法,检查键是否存在,如果不存在则 returns 默认值,而不是引发异常。返回的默认值为 None
.
如果你这样做,你还需要设置一些合理的默认值,或者捕捉那些你正在转换值的情况(因为你不能转换 None
)。
最后,无论何时从文件中读取 - 您都应该始终假设数据是 malformed/junk 并进行一些防御性编程。在您的代码中,您假设 CCDTEMP
的返回值是一个数字,但如果文件已损坏或有空白怎么办?您的应用程序不处理这种情况。
下面是一些尝试捕获尽可能多的错误的代码:
DATEOBS_header = hdulist[0].header.get('DATE-OBS')
XBINNING_header = hdulist[0].header.get('XBINNING')
FILTER_header = hdulist[0].header.get('FILTER')
IMAGETYP_header = hdulist[0].header.get('IMAGETYP')
OBJECT_header = hdulist[0].header.get('OBJECT')
# For these two, you need to either set a default
# Here I am setting the default to 0, ------------v
EXPTIME_header = int(round(hdulist[0].header.get('EXPTIME', 0)))
# Or you need to check for a value :
ccdtemp_value = hdulist[0].header.get('CCD-TEMP')
try:
ccdtemp_value = int(round(ccdtemp_value))
except ValueError:
# This means, the value was either None (header does not exist)
# or it was something that can't be converted to a number
# since it cannot be converted to a number, we do not know
# if the value is None or something like an empty string,
# so we explicitly set the value to None
ccdtemp_value = None
CCDTEMP_header = ccdtemp_value