2016-03-25 17 views
2

Ich mache ein Programm, das den Computer nach .fts- und .fits-Dateien durchsucht, in denen es die Datei öffnet und Informationen abruft, die einem bestimmten Schlüsselwort in der Kopfzeile entsprechen, und benennt die Datei in dieses Schlüsselwort um.Was kann ich für mein Programm tun, um keinen KeyError für einen Header zu erzeugen, der nicht in einer .fits Datei existiert?

Ich habe ein Problem, wo ich einen KeyError erhalten, weil ein Header-Schlüsselwort, das ich suche, nicht in der Datei gefunden wird. Gibt es einen Weg dahin? Ich möchte in der Lage sein, verschiedene Schlüsselwörter zu suchen und etwas zu tun, selbst wenn dieses Schlüsselwort in der Datei nicht existiert.

Hier Code:

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 

Dies ist der Fehler erhalte ich:

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." 
+1

Es klingt wie Sie eine Ausnahmebehandlung –

+3

ausführen müssen https://docs.python.org/3.5/tutorial/errors .html # handling-exceptions – Evert

+0

Sie können auch einen Standardwert verwenden, indem Sie etwas wie 'DATEOBS_header = hdulist [0] .header.get ('DATE-OBS', some_default_value)' verwenden. – Evert

Antwort

4

Um diese Arten von Ausnahmen vom Stoppen Ihres Programms zu verhindern, können Sie sie entweder, wie diese fangen:

try: 
    DATEOBS_header = hdulist[0].header['DATE-OBS'] 
except KeyError: 
    DATEOBS_header = None 

Oder verwenden Sie die .get() Methode der Wörterbücher, die, wenn ein Schlüssel überprüft vorhanden ist, und wenn es doesn 't gibt einen Standardwert zurück, anstatt eine Ausnahme auszulösen. Der Standardwert ist None.

Wenn Sie dies tun, müssen Sie auch einige sinnvolle Standardeinstellungen festlegen oder die Fälle abfangen, in denen Sie die Werte übertragen (da None nicht umgewandelt werden kann).

Schließlich, wann immer Sie von Dateien lesen - Sie sollten immer davon ausgehen, dass die Daten missgebildet/Junk und ein wenig defensive Programmierung sind. In Ihrem Code gehen Sie davon aus, dass die für CCDTEMP zurückgegebenen Werte eine Zahl sind. Was aber, wenn die Datei beschädigt ist oder leer ist? Ihre Anwendung behandelt diesen Fall nicht.

Hier ist ein Code, der so viele Fehler wie möglich zu fangen versucht:

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 
+0

Sieht gut aus mit mir –

+0

wenn Sie einen Standardwert, gibt es den Standardwert zurück, wenn das Schlüsselwort nicht gefunden wird? Zum Beispiel, in dem Code oben, wo es heißt ccdtemp_value = hdulist [0] .header.get ('CCD-TEMP') 'wenn CCD-TEMP nicht gefunden wird es 0 zurückgeben? –

+0

Der Standard-Rückgabewert, wenn der Schlüssel nicht gefunden wird, ist 'None'. Wenn Sie ihn also auf Null setzen möchten, müssen Sie ihn wie folgt übergeben:' ccdtemp_value = hdulist [0] .header.get ('CCD- TEMP ', 0) ' –

0

Unter der Annahme, hdulist[0].header gibt Ihnen eine dict Beispiel können Sie so etwas wie

DATEOBS_header = hdulist[0].header.get('DATE-OBS') 

tun Welche würde einen None zurückgeben, wenn der Schlüssel 'DATE-OBS' existiert nicht.

Weitere Details finden Sie unter https://docs.python.org/2/library/stdtypes.html#dict.get.

+1

'hdulist [0] .header' ist keine dict- oder dict-Unterklasse, aber es verhält sich ähnlich. – Evert