Index: trunk/ippToPsps/jython/detectionbatch.py
===================================================================
--- trunk/ippToPsps/jython/detectionbatch.py	(revision 39133)
+++ trunk/ippToPsps/jython/detectionbatch.py	(revision 39305)
@@ -149,4 +149,8 @@
         sqlLine.group("analysisVer",           self.analysisVer);
         sqlLine.group("md5sum",                str(self.md5sum))
+
+        # these lines should write "NULL" if the header contains NaN -- NULLs are converted below
+        # to -999 for the sql database (a terrible solution, but mandatory?)
+
         sqlLine.group("photoScat",             self.getKeyFloat(self.header, "%.8f", 'ZPT_ERR'));
         sqlLine.group("expStart",              self.getKeyFloat(self.header, "%.10f", 'MJD-OBS'));
@@ -218,11 +222,30 @@
         else: ccdID = 0
 
+        ### any operations below which act on the output of getKeyFloat need to be 
+        ### able to handle NULL results.
+
         # XXX hard-wired platescale : 0.257
         pltscale = 0.257
         pltscale2 = pltscale * pltscale
 
-        psfFwhmMajor = pltscale * self.getKeyFloat(header, "%.8f", 'FWHM_MAJ')
-        psfFwhmMinor = pltscale * self.getKeyFloat(header, "%.8f", 'FWHM_MIN')
-        psfFWHM = 0.5*(psfFwhmMajor + psfFwhmMinor)
+        # NOTE: getKeyFloat returns the header value if it is a float,
+        # -999 if the value is missing and "NULL" if the value in the
+        # header is a NaN.  any math operations below need to handle
+        # these cases correctly
+
+        # NOTE 2: getKeyFloat NOW returns the header value if it is a
+        # float or "NULL" if the value is missing or if the value in
+        # the header is a NaN.  any math operations below need to
+        # handle these cases correctly
+
+        psfFwhmMajor = self.getKeyFloat(header, "%.8f", 'FWHM_MAJ')
+        if (psfFwhmMajor != "NULL"): psfFwhmMajor *= pltscale
+
+        psfFwhmMinor = self.getKeyFloat(header, "%.8f", 'FWHM_MIN')
+        if (psfFwhmMinor != "NULL"): psfFwhmMinor *= pltscale
+
+        psfFWHM = "NULL"
+        if (psfFwhmMajor != "NULL") and (psfFwhmMinor != "NULL"):
+            psfFWHM = 0.5*(psfFwhmMajor + psfFwhmMinor)
 
         psfmodel_name = self.getKeyValue(header, 'PSFMODEL')
@@ -231,16 +254,39 @@
         ast_cdx = self.getKeyFloat(header, "%.8f",'AST_CDX')
         ast_cdy = self.getKeyFloat(header, "%.8f",'AST_CDY')
-        astroscat = math.sqrt(ast_cdx**2 + ast_cdy**2)
+
+        astroscat = "NULL"
+        if (ast_cdx != "NULL") and (ast_cdy != "NULL"):
+            astroscat = math.sqrt(ast_cdx**2 + ast_cdy**2)
         
         # Convert detectionThreshold to appropriate magnitudes
-        detectionThreshold = self.getKeyFloat(header, "%.8f", 'DETEFF.MAGREF')
+        magref  = self.getKeyFloat(header, "%.8f", 'DETEFF.MAGREF')
         expTime = self.getKeyFloat(header, "%.8f", 'EXPTIME')
         zp      = self.getKeyFloat(header, "%.8f", 'ZPT_OBS')
 
+        # zp correction from DVO
         zpImage = self.scratchDb.getImageZeroPoint(self.imageIDs[ota])
 
-        # XXX zp correction should come from DVO
-        detectionThreshold = detectionThreshold + zpImage + 2.5 * math.log10(expTime)
-        
+        if (zpImage == "NULL"):
+            zpImage = zp
+
+        detectionThreshold = "NULL"
+        if (magref != "NULL") and (zpImage != "NULL") and (expTime != "NULL"):
+            detectionThreshold = magref + zpImage + 2.5 * math.log10(expTime)
+        
+        # other header fields which depend on pltscale:
+        momentMajor =        self.getKeyFloat(header, "%.8f", 'IQ_FW1'))
+        momentMinor =        self.getKeyFloat(header, "%.8f", 'IQ_FW2'))
+        momentM2C =          self.getKeyFloat(header, "%.8f", 'IQ_M2C'))
+        momentM2S =          self.getKeyFloat(header, "%.8f", 'IQ_M2S'))
+        momentM3 =           self.getKeyFloat(header, "%.8f", 'IQ_M3'))
+        momentM4 =           self.getKeyFloat(header, "%.8f", 'IQ_M4'))
+
+        if (momentMajor != "NULL"): momentMajor *= pltscale
+        if (momentMinor != "NULL"): momentMinor *= pltscale
+        if (momentM2C   != "NULL"): momentM2C   *= pltscale2
+        if (momentM2S   != "NULL"): momentM2S   *= pltscale2
+        if (momentM3    != "NULL"): momentM3    *= pltscale2
+        if (momentM4    != "NULL"): momentM4    *= pltscale2
+
         # insert image metadata into table
         sqlLine = sqlUtility("INSERT INTO " + tableName + "(")
@@ -265,10 +311,10 @@
         sqlLine.group("psfWidMinor",        psfFwhmMinor)
         sqlLine.group("psfTheta",           self.getKeyFloat(header, "%.8f", 'ANGLE'))
-        sqlLine.group("momentMajor",        pltscale * self.getKeyFloat(header, "%.8f", 'IQ_FW1'))
-        sqlLine.group("momentMinor",        pltscale * self.getKeyFloat(header, "%.8f", 'IQ_FW2'))
-        sqlLine.group("momentM2C",          pltscale2 * self.getKeyFloat(header, "%.8f", 'IQ_M2C'))
-        sqlLine.group("momentM2S",          pltscale2 * self.getKeyFloat(header, "%.8f", 'IQ_M2S'))
-        sqlLine.group("momentM3",           pltscale2 * self.getKeyFloat(header, "%.8f", 'IQ_M3'))
-        sqlLine.group("momentM4",           pltscale2 * self.getKeyFloat(header, "%.8f", 'IQ_M4'))
+        sqlLine.group("momentMajor",        momentMajor)
+        sqlLine.group("momentMinor",        momentMinor)
+        sqlLine.group("momentM2C",          momentM2C)
+        sqlLine.group("momentM2S",          momentM2S)
+        sqlLine.group("momentM3",           momentM3)
+        sqlLine.group("momentM4",           momentM4)
         sqlLine.group("apResid",            self.getKeyFloat(header, "%.8f", 'APMIFIT'))
         sqlLine.group("dapResid",           self.getKeyFloat(header, "%.8f", 'DAPMIFIT'))
@@ -374,6 +420,5 @@
         # CZW: 20151110 This needs to get the deteff header as well.
         nInjected = int(self.getKeyInt(deteffHeader, 0, 'DETEFF.NUM'))
-        magref = self.getKeyFloat(deteffHeader, "%.8f", 'DETEFF.MAGREF')
-
+        magref  = self.getKeyFloat(deteffHeader, "%.8f", 'DETEFF.MAGREF')
         expTime = self.getKeyFloat(header, "%.8f", 'EXPTIME')
         zp      = self.getKeyFloat(header, "%.8f", 'ZPT_OBS')
@@ -382,8 +427,10 @@
         zpImage = self.scratchDb.getImageZeroPoint(self.imageIDs[ota])
 
-        if zpImage < 0.0:
+        if (zpImage == "NULL"):
             zpImage = zp
 
-        detectionThreshold = magref + zpImage + 2.5 * math.log10(expTime)
+        detectionThreshold = "NULL"
+        if (magref != "NULL") and (zpImage != "NULL") and (expTime != "NULL"):
+            detectionThreshold = magref + zpImage + 2.5 * math.log10(expTime)
 
         sqlLine.group("frameID",          str(self.expID))
