Index: /trunk/ippToPsps/jython/fits.py
===================================================================
--- /trunk/ippToPsps/jython/fits.py	(revision 31832)
+++ /trunk/ippToPsps/jython/fits.py	(revision 31832)
@@ -0,0 +1,113 @@
+#!/usr/bin/env jython
+
+import os
+import re
+
+
+'''
+FITS file class, for reading silly headers and things
+'''
+class Fits(object):
+
+
+    '''
+    Constructor
+
+    '''
+    def __init__(self, logger, path):
+
+       self.path = path
+       self.logger = logger
+
+       # does it exist?
+       if not os.path.isfile(self.path): 
+           self.logger.error("Cannot read file at '" + self.path + "'")
+           return
+
+       self.file = open(self.path)
+       self.header = self.parseHeader()
+       self.logger.info("Read primary header and found " + str(len(self.header)) + " header cards")
+       self.rewindToStart()
+
+    '''
+    Returns the primary header as a dictionary object
+    '''
+    def getPrimaryHeader(self):
+        return self.header
+
+    '''
+    Returns the value associated with this key in the primary header, or NULL (as a string) otherwise
+    '''
+    def getPrimaryHeaderValue(self, key):
+
+        if key in self.header: return self.header[key]
+        else: return "NULL"
+
+
+    def rewindToStart(self):
+        self.file.seek(0, 0)
+
+
+    '''
+    Finds and reads a header extension
+    '''
+    def findAndReadHeader(self, name):
+
+        found = False
+
+        origIndex = self.file.tell()
+        while True:
+
+            index = self.file.tell()
+
+            record = self.file.read(80)
+            if not record: break;
+
+            # quit when we reach 'END'
+            if record.startswith("XTENSION= 'IMAGE"):
+
+                header = self.parseHeader()
+                if header['EXTNAME'] == name:
+                    found = True
+                    self.file.seek(index + 2880, 0)
+                    break
+
+            self.file.seek(index + 2880, 0)
+
+        if found != True:
+
+            self.file.seek(origIndex, 0)
+            self.logger.error("...could not read header in extension '" + name + "'")
+            return
+    #else: self.logger.info("...read header at '" + name + "' and found " + str(len(header)) + " header cards") 
+
+        return header
+
+
+    '''
+    Reads FITS header and stores all fields in a dictionary object
+    '''
+    def parseHeader(self):
+
+        header = {}
+
+        while (True):
+
+            record = self.file.read(80)
+
+            # quit when we reach 'END'
+            if re.match('END\s+', record): break
+
+            # this regex will get param/value pairs for all header cards, ignoring comments and parsing out 'HIERACH' prefixes
+            match = re.match('^(HIERARCH )*([a-zA-Z0-9-_\.]+)\s*=\s+\'*([a-zA-Z0-9-_\.:\s@#]+)\'*\\/*', record)
+            if match:
+
+                param = match.group(2)
+                value = match.group(3).strip()
+                if value == "NaN": value = "NULL"
+                header[param] = value
+
+                #print param + "|" + value + "|"
+
+        return header
+
