正如 anatoly techtonik指出的那样,FITS 标头中的非 ASCII 字符完全无效,并使 FITS 文件无效。astropy.io.fits
也就是说,如果至少可以读取无效条目,那就太好了。对此的支持目前已被破坏,需要英雄来修复它,但没有人拥有,因为它是一个不常见的问题,大多数人在一两个文件中遇到它,修复这些文件,然后继续。不过希望有人能解决这个问题。
同时,由于您确切知道该文件在打什么字符串,所以我只需以原始二进制模式打开该文件并替换该字符串。如果 FITS 文件非常大,您可以一次读取一个块并在这些块上进行替换。FITS 文件(尤其是标头)以 2880 字节块编写,因此您知道该字符串出现的任何位置都将与这样的块对齐,并且您无需对标头格式进行任何解析。只需确保您替换它的字符串不长于原始字符串,并且如果它更短,则在右边用空格填充,因为 FITS 标题是固定宽度格式,任何改变标题长度的东西都会损坏整个文件。对于这种特殊情况,我会尝试这样的事情:
bad_str = 'Uni Göttingen, Institut für Astrophysik'.encode('latin1')
good_str = 'Uni Gottingen, Institut fur Astrophysik'.encode('ascii')
# In this case I already know the replacement is the same length so I'm no worried about it
# A more general solution would require fixing the header parser to deal with non-ASCII bytes
# in some consistent manner; I'm also looking for the full string instead of the individual
# characters so that I don't corrupt binary data in the non-header blocks
in_filename = 'Jupiter.FIT'
out_filename = 'Jupiter-fixed.fits'
with open(in_filename, 'rb') as inf, open(out_filename, 'wb') as outf:
while True:
block = inf.read(2880)
if not block:
break
block = block.replace(bad_str, good_str)
outf.write(block)
这很难看,对于一个非常大的文件可能会很慢,但这是一个开始。我可以想到更好的解决方案,但如果您只有少量文件要修复,则更难理解并且可能不值得花时间。
完成后,请与文件的创建者进行严厉的交谈——他们不应该发布损坏的 FITS 文件。