Как указал анатолий техтоник, не-ASCII-символы в заголовках FITS совершенно недействительны и делают недействительными файлы 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.
person
Iguananaut
schedule
22.09.2016
'Uni G\xf6ttingen, Institut f\xfcr Astrophysik'
это не UTF-8, это (вероятно) кодировка Latin1 для'Uni Göttingen, Institut für Astrophysik'
; эквивалент UTF-8 -'Uni G\xc3\xb6ttingen, Institut f\xc3\xbcr Astrophysik'
- person PM 2Ring   schedule 21.09.2016