2016-09-21 7 views
0

Ich habe mit einigen passt Dateien, die utf8 Text in ihrer Kopfzeile enthalten beschäftigen. Das bedeutet, dass grundsätzlich alle Funktionen des pyfits-Pakets nicht funktionieren. Auch .decode funktioniert nicht, da die passt Header eine Klasse ist keine Liste. Kann jemand den Header dekodieren, damit ich die Daten verarbeiten kann? Der eigentliche Inhalt ist nicht so wichtig, so etwas wie das Ignorieren der Buchstaben ist in Ordnung. Meine aktuellen Code sieht wie folgt aus:Öffnen/bearbeiten utf8 passt Header in Python (pyfits)

hdulist = fits.open('Jupiter.FIT') 
hdu = hdulist[0].header 
hdu.decode('ascii', errors='ignore') 

Und ich bekomme: Attribute: 'Header' Objekt kein Attribut 'decode'

Funktionen wie hat:

print (hdu) 

Rückkehr:

ValueError: FITS header values must contain standard printable ASCII characters; "'Uni G\xf6ttingen, Institut f\xfcr Astrophysik'" contains characters/bytes that do not represent printable characters in ASCII. 

Ich dachte daran, etwas in den Eintrag zu schreiben, so dass ich mich nicht darum kümmern muss. Jedoch kann ich sogar herausfinden, welcher Eintrag die schlechten Zeichen enthält, und ich möchte eine Batch-Lösung haben, da ich einige hundert Dateien habe.

+0

''Uni G \ xföttingen, Institut f \ xfcr Astrophysik' 'ist nicht UTF-8, es ist (wahrscheinlich) die Latin1-Kodierung von' 'Uni Göttingen, Institut für Astrophysik' '; das Äquivalent UTF-8 ist "Uni G \ xc3 \ xb6ttingen, Institut f \ xc3 \ xbcr Astrophysik" –

Antwort

1

Als anatoly Techtonik pointed out Nicht-ASCII-Zeichen in FITS-Header völlig ungültig sind und ungültig FITS machen Dateien. Das heißt, es wäre schön, wenn astropy.io.fits zumindest die ungültigen Einträge lesen könnte. Die Unterstützung dafür ist derzeit kaputt und benötigt einen Champion, um es zu beheben, aber niemand hat es, weil es ein selten genug Problem ist, und die meisten Leute treffen es in einer oder zwei Dateien, reparieren diese Dateien und gehen weiter. Würde mich freuen, wenn jemand das Problem angehen würde.

In der Zwischenzeit, da Sie genau wissen, welche Zeichenfolge diese Datei auf Schluckauf ist, würde ich nur die Datei im rohen Binärmodus öffnen und die Zeichenfolge ersetzen. Wenn die FITS-Datei sehr groß ist, können Sie sie blockweise lesen und die Blöcke austauschen. FITS-Dateien (insbesondere Header) werden in 2880-Byte-Blöcken geschrieben, sodass Sie wissen, dass die Stelle, an der diese Zeichenfolge angezeigt wird, an einem solchen Block ausgerichtet ist und Sie darüber hinaus kein Header-Format analysieren müssen. Stellen Sie nur sicher, dass die Zeichenfolge, durch die Sie es ersetzen, nicht länger als die ursprüngliche Zeichenfolge ist, und dass es, wenn es kürzer ist, mit Leerzeichen aufgefüllt wird, da FITS-Header ein Format fester Breite und alles, das die Länge eines Headers ändert Die gesamte Datei wird beschädigt. Für diesen speziellen Fall ist, dann würde ich so etwas wie dies versucht:

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) 

Dies ist hässlich, und für eine sehr große Datei kann langsam sein, aber es ist ein Anfang. Ich kann mir bessere Lösungen ausdenken, aber diese sind schwerer zu verstehen und es lohnt sich wahrscheinlich nicht, sich die Zeit zu nehmen, wenn Sie nur eine Handvoll Dateien reparieren müssen.

Sobald dies erledigt ist, geben Sie bitte dem Urheber der Datei ein ernstes Gespräch - sie sollten keine korrupten FITS-Dateien veröffentlichen.

+0

Mit diesem Code bekomme ich: SyntaxError: Non- ASCII-Zeichen '\ xc3' in Datei .... py in Zeile 103, aber keine Codierung deklariert; Details finden Sie unter http://python.org/dev/peps/pep-0263/. Grundsätzlich kann ich den Badstring in meiner Python-Datei nicht definieren. –

+0

Ich meine, ich hätte dies gerade im IPython-Interpreter oder so gemacht, aber wenn Sie es in eine Datei einfügen möchten, können Sie tun, wie es in PEP-263 sagt und fügen Sie '# coding = utf-8' an die Spitze von die Datei. In Python 3 ist dies der Standard, denke ich. – Iguananaut

+0

Jetzt bekomme ich: bad_str = 'Uni Göttingen, Institut für Astrophysik'.encode (' latin1 ') UnicodeDecodeError:' ascii 'Codec kann Byte 0xc3 in Position 5 nicht dekodieren: Ordnungszahl nicht im Bereich (128) Sorry wenn ich scheine dumm ich bin ziemlich neu bei Python. –

0

Sieht aus wie PyFITS unterstützt es einfach nicht (noch?)

Von https://github.com/astropy/astropy/issues/3497:

FITS predates unicode and has never been updated to support anything beyond the ASCII printable characters for data. It is impossible to encode non-ASCII characters in FITS headers.

+0

gibt es eine Möglichkeit, herauszufinden, welche Einträge beschädigt sind und überschreiben sie einfach? –

+1

@ user6858243 ist es möglich, Dateiinhalte mit https: // pymotw zu filtern.com/2/codecs/# error-handling, aber ich schlage vor, dass Sie die Entwickler fragen, wie Sie damit richtig umgehen können - https://github.com/astropy/astropy/issues/3497 –