Index: /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 25157)
+++ /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 25158)
@@ -296,6 +296,6 @@
       value.Flt = pow (10.0, measure[0].dt * 0.4);
       break;
-    case MEAS_PHOTCODE: /* OK */
-      value.Int = measure[0].photcode;
+    case MEAS_PHOTCODE_EQUIV: /* OK */
+      value.Int = GetPhotcodeEquivCodebyCode (measure[0].photcode);
       break;
     case MEAS_TIME: /* OK */
Index: /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbFields.c	(revision 25157)
+++ /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbFields.c	(revision 25158)
@@ -11,5 +11,5 @@
     if (fields[i].photcode != NULL) {
       if (fields[i].photcode[0].type == PHOT_MAG) {
-	free (fields[i].photcode);
+        free (fields[i].photcode);
       }
     }
@@ -30,18 +30,18 @@
 int GetMagMode (char *string) {
 
-  if (!strcasecmp (string, "inst"))  	 return (MAG_INST);
-  if (!strcasecmp (string, "cat"))   	 return (MAG_CAT);
-  if (!strcasecmp (string, "sys"))   	 return (MAG_SYS);
-  if (!strcasecmp (string, "rel"))   	 return (MAG_REL);
-  if (!strcasecmp (string, "cal"))   	 return (MAG_CAL);
-  if (!strcasecmp (string, "ave"))   	 return (MAG_AVE);
-  if (!strcasecmp (string, "ref"))   	 return (MAG_REF);
-  if (!strcasecmp (string, "ap"))   	 return (MAG_APER);
-  if (!strcasecmp (string, "aper"))   	 return (MAG_APER);
-  if (!strcasecmp (string, "err"))   	 return (MAG_ERR);
+  if (!strcasecmp (string, "inst"))      return (MAG_INST);
+  if (!strcasecmp (string, "cat"))       return (MAG_CAT);
+  if (!strcasecmp (string, "sys"))       return (MAG_SYS);
+  if (!strcasecmp (string, "rel"))       return (MAG_REL);
+  if (!strcasecmp (string, "cal"))       return (MAG_CAL);
+  if (!strcasecmp (string, "ave"))       return (MAG_AVE);
+  if (!strcasecmp (string, "ref"))       return (MAG_REF);
+  if (!strcasecmp (string, "ap"))        return (MAG_APER);
+  if (!strcasecmp (string, "aper"))      return (MAG_APER);
+  if (!strcasecmp (string, "err"))       return (MAG_ERR);
   if (!strcasecmp (string, "photflags")) return (MAG_PHOT_FLAGS);
-  if (!strcasecmp (string, "chisq")) 	 return (MAG_CHISQ);
-  if (!strcasecmp (string, "ncode")) 	 return (MAG_NCODE);
-  if (!strcasecmp (string, "nphot")) 	 return (MAG_NPHOT);
+  if (!strcasecmp (string, "chisq"))     return (MAG_CHISQ);
+  if (!strcasecmp (string, "ncode"))     return (MAG_NCODE);
+  if (!strcasecmp (string, "nphot"))     return (MAG_NPHOT);
   return (MAG_NONE);
 }
@@ -140,59 +140,60 @@
   }
 
-  if (!strcasecmp (fieldName, "RA"))         ESCAPE (MEAS_RA,   	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC"))        ESCAPE (MEAS_DEC,  	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "RA:AVE"))     ESCAPE (MEAS_RA_AVE,      	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC:AVE"))    ESCAPE (MEAS_DEC_AVE,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "RA:ERR"))     ESCAPE (MEAS_RA_AVE_ERR,  	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC:ERR"))    ESCAPE (MEAS_DEC_AVE_ERR, 	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uRA"))        ESCAPE (MEAS_U_RA,        	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uDEC"))       ESCAPE (MEAS_U_DEC,       	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duRA"))       ESCAPE (MEAS_U_RA_ERR,    	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duDEC"))      ESCAPE (MEAS_U_DEC_ERR,   	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PAR"))        ESCAPE (MEAS_PAR,         	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dPAR"))       ESCAPE (MEAS_PAR_ERR,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR"))         ESCAPE (MEAS_RA_OFFSET,   	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD"))         ESCAPE (MEAS_DEC_OFFSET,  	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR:FIT"))     ESCAPE (MEAS_RA_FIT_OFFSET,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD:FIT"))     ESCAPE (MEAS_DEC_FIT_OFFSET, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR:ERR"))     ESCAPE (MEAS_RA_OFFSET_ERR,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD:ERR"))     ESCAPE (MEAS_DEC_OFFSET_ERR, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "xp"))         ESCAPE (MEAS_XP,          	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "nmeas"))      ESCAPE (MEAS_NMEAS,       	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "nmiss"))      ESCAPE (MEAS_NMISS,       	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "objflags"))   ESCAPE (MEAS_OBJFLAGS,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "AIRMASS"))    ESCAPE (MEAS_AIRMASS,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ALT"))        ESCAPE (MEAS_ALT,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "AZ"))         ESCAPE (MEAS_AZ,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "EXPTIME"))    ESCAPE (MEAS_EXPTIME,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PHOTCODE"))   ESCAPE (MEAS_PHOTCODE,    	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "TIME"))       ESCAPE (MEAS_TIME,        	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM"))       ESCAPE (MEAS_FWHM,        	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJ"))   ESCAPE (MEAS_FWHM_MAJ,    	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MIN"))   ESCAPE (MEAS_FWHM_MIN,    	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "THETA"))      ESCAPE (MEAS_THETA,       	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DOPHOT"))     ESCAPE (MEAS_DOPHOT,      	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "DB_FLAGS"))   ESCAPE (MEAS_DB_FLAGS,    	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PHOT_FLAGS")) ESCAPE (MEAS_PHOT_FLAGS, 	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "XCCD"))       ESCAPE (MEAS_XCCD, 	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCCD"))       ESCAPE (MEAS_YCCD, 	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XCCD:ERR"))   ESCAPE (MEAS_XCCD_ERR, 	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCCD:ERR"))   ESCAPE (MEAS_YCCD_ERR, 	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XMOSAIC"))    ESCAPE (MEAS_XMOSAIC,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YMOSAIC"))    ESCAPE (MEAS_YMOSAIC,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XCHIP"))      ESCAPE (MEAS_XCCD, 	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCHIP"))      ESCAPE (MEAS_YCCD, 	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XFPA"))       ESCAPE (MEAS_XMOSAIC,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YFPA"))       ESCAPE (MEAS_YMOSAIC,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DETID"))      ESCAPE (MEAS_DET_ID,     	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJID"))      ESCAPE (MEAS_OBJ_ID,     	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "CATID"))      ESCAPE (MEAS_CAT_ID,     	  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "IMAGEID"))    ESCAPE (MEAS_IMAGE_ID,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PSF_QF"))     ESCAPE (MEAS_PSF_QF,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PSF_CHISQ"))  ESCAPE (MEAS_PSF_CHISQ,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "CR_NSIGMA"))  ESCAPE (MEAS_CR_NSIGMA,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "EXT_NSIGMA")) ESCAPE (MEAS_EXT_NSIGMA,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "SKY"))        ESCAPE (MEAS_SKY,     	  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "SKY_ERR"))    ESCAPE (MEAS_dSKY,     	  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "RA"))         	 ESCAPE (MEAS_RA,             MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC"))        	 ESCAPE (MEAS_DEC,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "RA:AVE"))     	 ESCAPE (MEAS_RA_AVE,         MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC:AVE"))    	 ESCAPE (MEAS_DEC_AVE,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "RA:ERR"))     	 ESCAPE (MEAS_RA_AVE_ERR,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC:ERR"))    	 ESCAPE (MEAS_DEC_AVE_ERR,    MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uRA"))        	 ESCAPE (MEAS_U_RA,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uDEC"))       	 ESCAPE (MEAS_U_DEC,          MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duRA"))       	 ESCAPE (MEAS_U_RA_ERR,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duDEC"))      	 ESCAPE (MEAS_U_DEC_ERR,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PAR"))        	 ESCAPE (MEAS_PAR,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dPAR"))       	 ESCAPE (MEAS_PAR_ERR,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR"))         	 ESCAPE (MEAS_RA_OFFSET,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD"))         	 ESCAPE (MEAS_DEC_OFFSET,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR:FIT"))     	 ESCAPE (MEAS_RA_FIT_OFFSET,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD:FIT"))     	 ESCAPE (MEAS_DEC_FIT_OFFSET, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR:ERR"))     	 ESCAPE (MEAS_RA_OFFSET_ERR,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD:ERR"))     	 ESCAPE (MEAS_DEC_OFFSET_ERR, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "xp"))         	 ESCAPE (MEAS_XP,             MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "nmeas"))      	 ESCAPE (MEAS_NMEAS,          MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "nmiss"))      	 ESCAPE (MEAS_NMISS,          MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "objflags"))   	 ESCAPE (MEAS_OBJFLAGS,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "AIRMASS"))    	 ESCAPE (MEAS_AIRMASS,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ALT"))        	 ESCAPE (MEAS_ALT,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "AZ"))         	 ESCAPE (MEAS_AZ,             MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "EXPTIME"))    	 ESCAPE (MEAS_EXPTIME,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PHOTCODE"))   	 ESCAPE (MEAS_PHOTCODE,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOTCODE:EQUIV")) ESCAPE (MEAS_PHOTCODE_EQUIV, MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "TIME"))       	 ESCAPE (MEAS_TIME,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM"))       	 ESCAPE (MEAS_FWHM,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJ"))   	 ESCAPE (MEAS_FWHM_MAJ,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MIN"))   	 ESCAPE (MEAS_FWHM_MIN,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "THETA"))      	 ESCAPE (MEAS_THETA,          MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DOPHOT"))     	 ESCAPE (MEAS_DOPHOT,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "DB_FLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOT_FLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "XCCD"))       	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCCD"))       	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XCCD:ERR"))   	 ESCAPE (MEAS_XCCD_ERR,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCCD:ERR"))   	 ESCAPE (MEAS_YCCD_ERR,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XMOSAIC"))    	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YMOSAIC"))    	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XCHIP"))      	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCHIP"))      	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XFPA"))       	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YFPA"))       	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DETID"))      	 ESCAPE (MEAS_DET_ID,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJID"))      	 ESCAPE (MEAS_OBJ_ID,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "CATID"))      	 ESCAPE (MEAS_CAT_ID,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "IMAGEID"))    	 ESCAPE (MEAS_IMAGE_ID,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PSF_QF"))     	 ESCAPE (MEAS_PSF_QF,         MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PSF_CHISQ"))  	 ESCAPE (MEAS_PSF_CHISQ,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "CR_NSIGMA"))  	 ESCAPE (MEAS_CR_NSIGMA,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "EXT_NSIGMA")) 	 ESCAPE (MEAS_EXT_NSIGMA,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "SKY"))        	 ESCAPE (MEAS_SKY,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "SKY_ERR"))    	 ESCAPE (MEAS_dSKY,           MAG_NONE, OPIHI_FLT);
 
   // for words that don't parse, try a photcode
Index: /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbStackOps.c
===================================================================
--- /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbStackOps.c	(revision 25157)
+++ /branches/czw_branch/cleanup/Ohana/src/opihi/dvo/dbStackOps.c	(revision 25158)
@@ -4,4 +4,7 @@
   stack[0].type   = DB_STACK_NONE;
   stack[0].name   = NULL;
+  stack[0].field  = 0;
+  stack[0].FltValue = 0.0;
+  stack[0].IntValue = 0;
 }
 
Index: /branches/czw_branch/cleanup/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /branches/czw_branch/cleanup/Ohana/src/opihi/include/dvoshell.h	(revision 25157)
+++ /branches/czw_branch/cleanup/Ohana/src/opihi/include/dvoshell.h	(revision 25158)
@@ -83,4 +83,5 @@
       MEAS_AZ, 
       MEAS_PHOTCODE, 
+      MEAS_PHOTCODE_EQUIV, 
       MEAS_TIME, 
       MEAS_FWHM, 
Index: /branches/czw_branch/cleanup/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm
===================================================================
--- /branches/czw_branch/cleanup/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm	(revision 25157)
+++ /branches/czw_branch/cleanup/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm	(revision 25158)
@@ -22,5 +22,4 @@
                     $PSTAMP_SELECT_MASK
                     $PSTAMP_SELECT_WEIGHT
-                    $PSTAMP_SELECT_INVERSE
                     $PSTAMP_SUCCESS
                     $PSTAMP_SYSTEM_ERROR
@@ -35,5 +34,4 @@
                     $PSTAMP_GONE
                     $PSTAMP_NO_JOBS_QUEUED
-                    $PSTAMP_NO_OVERLAP
                     );
 our %EXPORT_TAGS = (standard => [@EXPORT_OK]);
@@ -48,6 +46,4 @@
 our $PSTAMP_SELECT_WEIGHT    = 4;
 
-our $PSTAMP_SELECT_INVERSE   = 1024;
-
 # job and result codes
 # NOTE: these must match the values in pstamp/src/pstamp.h
@@ -55,5 +51,5 @@
 our $PSTAMP_SYSTEM_ERROR     = 10;
 our $PSTAMP_NOT_IMPLEMENTED  = 11;
-our $PSTAMP_UNKNOWN_ERROR    = 12;
+our $PSTAMP_UNKNOWN_ERROR   = 12;
 
 our $PSTAMP_DUP_REQUEST      = 20;
@@ -65,5 +61,4 @@
 our $PSTAMP_GONE             = 26;
 our $PSTAMP_NO_JOBS_QUEUED   = 27;
-our $PSTAMP_NO_OVERLAP       = 28;
 
 use IPC::Cmd 0.36 qw( can_run run );
Index: /branches/czw_branch/cleanup/ippScripts/scripts/publish_file.pl
===================================================================
--- /branches/czw_branch/cleanup/ippScripts/scripts/publish_file.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/ippScripts/scripts/publish_file.pl	(revision 25158)
@@ -83,5 +83,4 @@
 my %exp_id;                     # Exposure identifiers
 my %exp_name;                   # Exposure names
-my %direction;                  # Direction of subtraction
 {
     my $command;                # Command to run
@@ -115,21 +114,13 @@
         if ($stage eq 'diff') {
             my $skycell_id = $comp->{skycell_id};
-
-            # Positive direction
             $files{"$skycell_id.pos"} = $ipprc->filename( "PPSUB.OUTPUT.SOURCES", $path_base );
+            $files{"$skycell_id.neg"} = $ipprc->filename( "PPSUB.INVERSE.SOURCES", $path_base ) if
+                defined $comp->{bothways} and $comp->{bothways};
             $zp{"$skycell_id.pos"} = $zp;
+            $zp{"$skycell_id.neg"} = $zp if defined $comp->{bothways} and $comp->{bothways};
             $exp_id{"$skycell_id.pos"} = $comp->{exp_id_1};
+            $exp_id{"$skycell_id.neg"} = $comp->{exp_id_2} if defined $comp->{bothways} and $comp->{bothways};
             $exp_name{"$skycell_id.pos"} = $comp->{exp_name_1};
-            $direction{"$skycell_id.pos"} = 1;
-
-            # Negative direction
-            if (defined $comp->{bothways} and $comp->{bothways}) {
-                $files{"$skycell_id.neg"} = $ipprc->filename( "PPSUB.INVERSE.SOURCES", $path_base );
-                $zp{"$skycell_id.neg"} = $zp;
-                $exp_id{"$skycell_id.neg"} = $comp->{exp_id_2};
-                $direction{"$skycell_id.neg"} = 0;
-                $exp_name{"$skycell_id.neg"} = $comp->{exp_name_2};
-            }
-
+            $exp_name{"$skycell_id.neg"} = $comp->{exp_name_2} if defined $comp->{bothways} and $comp->{bothways};
         } elsif ($stage eq 'camera') {
             my $cam_id = $comp->{cam_id};
@@ -138,5 +129,4 @@
             $exp_id{$cam_id} = $comp->{exp_id};
             $exp_name{$cam_id} = $comp->{exp_name};
-            $direction{$cam_id} = 1;
         }
     }
@@ -155,5 +145,4 @@
     my $exp_id = $exp_id{$comp};
     my $exp_name = $exp_name{$comp};
-    my $direction = $direction{$comp};
     if ($product eq "IPP-MOPS") {
         my $outuri = "$outroot.$comp.fits";
@@ -161,5 +150,5 @@
             &my_die( "Unable to resolve output file $outuri", $pub_id, $PS_EXIT_SYS_ERROR);
 
-        my $command = "$ppMops $file $zp $exp_id $exp_name $direction $out";
+        my $command = "$ppMops $file $zp $exp_id $exp_name $out";
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
             run(command => $command, verbose => $verbose);
Index: /branches/czw_branch/cleanup/ippTasks/pstamp.pro
===================================================================
--- /branches/czw_branch/cleanup/ippTasks/pstamp.pro	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTasks/pstamp.pro	(revision 25158)
@@ -178,4 +178,6 @@
         book getword pstampRequest $pageName ds_outProduct -var PRODUCT
 
+        host anyhost
+
         $run = pstamp_parser_run.pl --req_id $REQ_ID --uri $URI --product $PRODUCT --redirect-output
 
@@ -374,4 +376,5 @@
         end
 
+        host anyhost
 
         $run = pstamp_job_run.pl --job_id $JOB_ID --job_type $JOB_TYPE --rownum $ROWNUM --output_base $OUTPUT_BASE --redirect-output 
Index: /branches/czw_branch/cleanup/ippTests/tap/mailTestResults.pl
===================================================================
--- /branches/czw_branch/cleanup/ippTests/tap/mailTestResults.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTests/tap/mailTestResults.pl	(revision 25158)
@@ -6,5 +6,5 @@
 use Email::Send;
 
-my $email="giebink\@ifa.hawaii.edu";
+my $email="ps-ipp-dev\@ifa.hawaii.edu";
 
 my $today = `date -u +%Y%m%d`;
Index: /branches/czw_branch/cleanup/ippTests/tap/proveParser.pl
===================================================================
--- /branches/czw_branch/cleanup/ippTests/tap/proveParser.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTests/tap/proveParser.pl	(revision 25158)
@@ -13,5 +13,5 @@
 while (<IF>) {
   print $_;
-  if (/Failed Test                      Stat Wstat Total Fail  List of Failed/) {
+  if (/^Failed Test/) {
     $flag = 1;
   }
Index: /branches/czw_branch/cleanup/ippTests/tap/tapTest.pl
===================================================================
--- /branches/czw_branch/cleanup/ippTests/tap/tapTest.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTests/tap/tapTest.pl	(revision 25158)
@@ -6,5 +6,5 @@
 
 #delete modules with tap tests
-system `rm -rf /data/ipp001.0/ippTests/tap/ipp/Nebulous/*`;
+system `rm -rf /data/ipp001.0/ippTests/tap/ipp/Nebulous`;
 
 #delete Nebulous binaries
@@ -28,5 +28,5 @@
         chdir "/data/ipp001.0/ippTests/tap/ipp/$dir/nebclient";
         system ("autogen.sh --prefix=/data/ipp001.0/ippTests/tap/usr");
-        system ("make");
+        system ("/usr/bin/make");
         chdir "/data/ipp001.0/ippTests/tap/ipp/$dir";
         system ("perl Build.PL --prefix=/data/ipp001.0/ippTests/tap/usr");
Index: /branches/czw_branch/cleanup/ippTools/share/Makefile.am
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/Makefile.am	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTools/share/Makefile.am	(revision 25158)
@@ -180,6 +180,4 @@
      magicdstool_torevert_warp.sql \
      magicdstool_torevert_diff.sql \
-     pstamptool_addjob_otherjob.sql \
-     pstamptool_addjob_stampjob.sql \
      pstamptool_datastore.sql \
      pstamptool_pendingjob.sql \
Index: /branches/czw_branch/cleanup/ippTools/share/difftool_skyfile.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/difftool_skyfile.sql	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTools/share/difftool_skyfile.sql	(revision 25158)
@@ -6,25 +6,43 @@
     diffRun.workdir,
     diffRun.bothways,
-    camProcessedExp.zpt_obs,
-    camProcessedExp.zpt_stdev,
-    camProcessedExp.zpt_lq,
-    camProcessedExp.zpt_uq,
-    rawExp.exp_time,
-    rawExp.camera,
     warp1,
     stack1,
     warp2,
-    stack2
+    stack2,
+    -- The following are only valid for warps
+    -- XXX This needs to be more clever to handle diffs between stacks
+    camProcessedInput.zpt_obs,
+    camProcessedInput.zpt_stdev,
+    camProcessedInput.zpt_lq,
+    camProcessedInput.zpt_uq,
+    rawInput.exp_time,
+    rawInput.camera,
+    rawInput.exp_name AS exp_name_1,
+    rawTemplate.exp_name AS exp_name_2,
+    rawInput.exp_id AS exp_id_1,
+    rawTemplate.exp_id AS exp_id_2
 FROM diffRun
 JOIN diffSkyfile USING(diff_id)
 JOIN diffInputSkyfile USING(diff_id, skycell_id)
-JOIN warpRun
--- NOTE: joining input only!
--- This is so that we can get the correct zero point
--- XXX This needs to be more clever to handle diffs between stacks
-    ON warpRun.warp_id = diffInputSkyfile.warp1
-JOIN fakeRun USING(fake_id)
-JOIN camRun USING(cam_id)
-JOIN camProcessedExp USING(cam_id)
-JOIN chipRun USING(chip_id)
-JOIN rawExp USING(exp_id)
+LEFT JOIN warpRun AS warpInput
+    ON warpInput.warp_id = diffInputSkyfile.warp1
+LEFT JOIN fakeRun AS fakeInput
+    ON fakeInput.fake_id = warpInput.fake_id
+LEFT JOIN camRun AS camInput
+    ON camInput.cam_id = fakeInput.cam_id
+LEFT JOIN camProcessedExp AS camProcessedInput
+    ON camProcessedInput.cam_id = camInput.cam_id
+LEFT JOIN chipRun AS chipInput
+    ON chipInput.chip_id = camInput.chip_id
+LEFT JOIN rawExp AS rawInput
+    ON rawInput.exp_id = chipInput.exp_id
+LEFT JOIN warpRun AS warpTemplate
+    ON warpTemplate.warp_id = diffInputSkyfile.warp2
+LEFT JOIN fakeRun AS fakeTemplate
+    ON fakeTemplate.fake_id = warpTemplate.fake_id
+LEFT JOIN camRun AS camTemplate
+    ON camTemplate.cam_id = fakeTemplate.cam_id
+LEFT JOIN chipRun AS chipTemplate
+    ON chipTemplate.chip_id = camTemplate.chip_id
+LEFT JOIN rawExp AS rawTemplate
+    ON rawTemplate.exp_id = chipTemplate.exp_id
Index: anches/czw_branch/cleanup/ippTools/share/pstamptool_addjob_otherjob.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/pstamptool_addjob_otherjob.sql	(revision 25157)
+++ 	(revision )
@@ -1,3 +1,0 @@
-INSERT INTO pstampJob
- (req_id, rownum, state, jobType, exp_id, outputBase, fault)
- VALUES( %lld, '%s', '%s', '%s', %lld, '%s', %s)
Index: anches/czw_branch/cleanup/ippTools/share/pstamptool_addjob_stampjob.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/pstamptool_addjob_stampjob.sql	(revision 25157)
+++ 	(revision )
@@ -1,3 +1,0 @@
-INSERT INTO pstampJob
- (req_id, rownum, state, jobType, exp_id, outputBase, fault)
- VALUES( %lld, '%s', '%s', '%s', %lld, '%s', %s)
Index: /branches/czw_branch/cleanup/ippTools/src/difftool.c
===================================================================
--- /branches/czw_branch/cleanup/ippTools/src/difftool.c	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTools/src/difftool.c	(revision 25158)
@@ -584,7 +584,7 @@
     PXOPT_COPY_STR(config->args, where, "-tess_id", "diffRun.tess_id", "==");
     PXOPT_COPY_S16(config->args, where, "-fault", "diffSkyfile.fault", "==");
-    PXOPT_COPY_S64(config->args, where, "-exp_id", "rawExp.exp_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-exp_name", "rawExp.exp_name", "==");
-    PXOPT_COPY_STR(config->args, where, "-warp_id", "warpRun.warp_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-exp_id", "rawInput.exp_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-exp_name", "rawInput.exp_name", "==");
+    PXOPT_COPY_STR(config->args, where, "-warp_id", "warpInput.warp_id", "==");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -1179,6 +1179,6 @@
 
         if (!available && (num != skycell_count)) {
-            psTrace("difftool", PS_LOG_INFO, "%" PRId64 " skyfiles with stack found for warp_id %"
-                PRId64 " need %" PRId64, num, skycell_count, warp_id);
+            psTrace("difftool", PS_LOG_INFO, "%" PRId64 " skyfiles with stack found for warp_id %" PRId64
+                    " need %" PRId64, num, warp_id, skycell_count);
             continue;
         }
Index: /branches/czw_branch/cleanup/ippTools/src/pstamptool.c
===================================================================
--- /branches/czw_branch/cleanup/ippTools/src/pstamptool.c	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTools/src/pstamptool.c	(revision 25158)
@@ -315,22 +315,16 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    psMetadata *where = psMetadataAlloc();
-    PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-name", "name", "==");
-
+    PXOPT_LOOKUP_S64(req_id,  config->args, "-req_id", false, false);
+    PXOPT_LOOKUP_STR(name,  config->args, "-name", false, false);
     PXOPT_LOOKUP_U64(limit,   config->args, "-limit",  false, false);
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
 
-    if (!psListLength(where->list)) {
+    if (!req_id && !name) {
         psError(PS_ERR_UNKNOWN, true, "-req_id or -name must be supplied");
         return false;
     }
 
-    psString query = psStringCopy("SELECT * from pstampRequest");
-
-    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-    psStringAppend(&query, " WHERE %s", whereClause);
-    psFree(whereClause);
-    psFree(where);
+    psString query = NULL;
+    psStringAppend(&query, "SELECT * from pstampRequest WHERE req_id = %" PRId64, req_id);
     
     // treat limit == 0 as "no limit"
@@ -529,5 +523,5 @@
 
     // default value for job_type is defined in pstamptoolConfig.c
-    if (!strcmp(job_type, "get_image") || !strcmp(job_type, "detect_query") || !strcmp(job_type, "none")) {
+    if (!strcmp(job_type, "get_image") || !strcmp(job_type, "detect_query")) {
 	stampJob = false;
     } else if (!strcmp(job_type, "stamp")) {
Index: /branches/czw_branch/cleanup/ippTools/src/pstamptoolConfig.c
===================================================================
--- /branches/czw_branch/cleanup/ippTools/src/pstamptoolConfig.c	(revision 25157)
+++ /branches/czw_branch/cleanup/ippTools/src/pstamptoolConfig.c	(revision 25158)
@@ -75,5 +75,6 @@
     // -listreq
     psMetadata *listreqArgs = psMetadataAlloc();
-    psMetadataAddS64(listreqArgs, PS_LIST_TAIL, "-req_id", 0,            "define req_id (required)", 0); 
+    psMetadataAddS64(listreqArgs, PS_LIST_TAIL, "-req_id", 0,            "list by req_id", 0); 
+    psMetadataAddStr(listreqArgs, PS_LIST_TAIL, "-name", 0,              "list by name", NULL); 
     psMetadataAddU64(listreqArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
     psMetadataAddBool(listreqArgs, PS_LIST_TAIL, "-simple", 0,            "use the simple output format", false);
@@ -106,5 +107,5 @@
     psMetadataAddStr(addjobArgs, PS_LIST_TAIL, "-state", 0,            "new state", "run"); 
     psMetadataAddS64(addjobArgs, PS_LIST_TAIL, "-exp_id", 0,           "exposure id", 0); 
-    psMetadataAddStr(addjobArgs, PS_LIST_TAIL, "-fault", 0,            "new result", NULL); 
+    psMetadataAddS16(addjobArgs, PS_LIST_TAIL, "-fault", 0,            "new result", 0); 
 
     // -listjob
Index: /branches/czw_branch/cleanup/magic/Makefile.in
===================================================================
--- /branches/czw_branch/cleanup/magic/Makefile.in	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/Makefile.in	(revision 25158)
@@ -12,5 +12,5 @@
 
 update:
-	# get the source code (replace this with SVN interactions)
+# get the source code (replace this with SVN interactions)
 	tar xvzf ~/magic.tgz
 	tar xvzf ~/ssa-core-cpp.tgz
Index: /branches/czw_branch/cleanup/magic/censorObjects/src/censorLoop.c
===================================================================
--- /branches/czw_branch/cleanup/magic/censorObjects/src/censorLoop.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/censorObjects/src/censorLoop.c	(revision 25158)
@@ -22,5 +22,4 @@
  */
 bool censorLoop (pmConfig *config) {
-
     pmChip *chip;
     pmCell *cell;
@@ -28,4 +27,7 @@
 
     psTimerStart ("censor");
+
+
+
 
     // select the current recipe
@@ -51,4 +53,5 @@
 
     pmFPAview *view = pmFPAviewAlloc (0);
+
     bool badMaskFile = false;
 
@@ -59,12 +62,39 @@
     if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE;
 
+    // check PHU header to see if we are using mosaic-level or per-chip astrometry
+    bool bilevelAstrometry = false;
+    pmHDU *phu = pmFPAviewThisPHU (view, input->fpa);
+    if (phu) {
+      char *ctype = psMetadataLookupStr (NULL, phu->header, "CTYPE1");
+      if (ctype) bilevelAstrometry = !strcmp (&ctype[4], "-DIS");
+    }
+    if (bilevelAstrometry) {
+      pmAstromReadBilevelMosaic (input->fpa, phu->header);
+    } 
+
     while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
 	psTrace ("censor", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
 	if (!chip->process || !chip->file_exists) { continue; }
-
+	
 	// check on the mask file at this level if possible
 	badMaskFile = censorBadFileByView(badMaskFile, inMask, config, view);
 
 	if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE;
+
+	// read WCS data from the corresponding header
+
+	pmHDU *hdu = pmFPAviewThisHDU (view, input->fpa);
+	
+	if (bilevelAstrometry) {
+	  if (!pmAstromReadBilevelChip (chip, hdu->header)) {
+	    psWarning("Could not get WCS information from header for chip %d, skipping", view->chip); 
+	    continue;
+	  }
+	} else {
+	  if (!pmAstromReadWCS(input->fpa, chip, hdu->header, 1.0)) {
+	    psWarning( "Unable to read WCS astrometry from chip %d, skipping", view->chip);
+	    continue;
+	  }
+	}
 
 	while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
Index: /branches/czw_branch/cleanup/magic/remove/src/Line.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/Line.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/Line.c	(revision 25158)
@@ -36,5 +36,5 @@
     // If the current line is not vertical, check to see if the point
     // is inside the two endpoints independent of direction
-    
+
     if (line->begin.x != line->end.x)
     {
@@ -59,11 +59,11 @@
     ux = line->end.x - line->begin.x;
     uy = line->end.y - line->begin.y;
-    
+
     vx = x - line->begin.x;
     vy = y - line->begin.y;
-    
+
     double u_u = ux * ux + uy * uy;                         // (u . u)
     double u_v = ux * vx + uy * vy;                         // (u . v)
-    
+
     if (u_v <= 0) return vx * vx + vy * vy;                 // (v . v)
     if (u_u <= u_v)
@@ -73,8 +73,8 @@
         return wx * wx + wy * wy;                           // (w . w)
     }
-    
+
     // Compute P(b) is the base of the perpendicular dropped from tuple to
     // the line
-    
+
     b = u_v / u_u;
     px = vx - b * ux;
@@ -109,25 +109,25 @@
     double wx  = first->begin.x - second->begin.x;
     double wy  = first->begin.y - second->begin.y;
-    
+
     // Calculate the perpendicular product, dt
-    
+
     double dt = dx1 * dy2 - dy1 * dx2;
-    
+
     // Are the lines parallel?
-    
+
     if (fabs (dt) <= 1e-8)
     {
         // Check to see if they are overlap
-        
+
         if (dx1 * wy - dy1 * wx != 0 || dx2 * wy - dy2 * wx != 0) return 0;
-        
+
         // The line are coplanar, so check to see if they are degenerate
-        
+
         len1 = dx1 * dx1 + dy1 * dy1;
         len2 = dx2 * dx2 + dy2 * dy2;
-        
+
         // First, check to see if both lines are points and if they are
         // distinct tuples
-        
+
         if (len1 == 0 && len2 == 0)
         {
@@ -137,8 +137,8 @@
             return 1;
         }
-        
+
         // Check to see if the first line is a point and is inside the
         // second line
-        
+
         if (len1 == 0)
         {
@@ -148,8 +148,8 @@
                 return 0;
         }
-        
+
         // Check to see if the second line is a point and is inside the
         // first line
-        
+
         if (len2 == 0)
         {
@@ -159,14 +159,14 @@
                 return 0;
         }
-        
+
         // Since both lines are coplanar and have length, search for
         // overlap tuples
-        
+
         w2x = first->end.x - second->begin.x;
         w2y = first->end.y - second->begin.y;
-        
+
         t0 = (dx2 != 0) ? wx  / dx2 : wy  / dy2;
         t1 = (dx2 != 0) ? w2x / dx2 : w2y / dy2;
-        
+
         if (t0 > t1) SwapDouble (&t0, &t1);
         if ((inFirstSegment || inSecondSegment) && (t0 > 1 || t1 < 0))
@@ -176,27 +176,27 @@
         t0 = (t0 < 0) ? 0 : t0;             // Clip to min 0
         t1 = (t1 > 1) ? 1 : t1;             // Clip to max 1
-        
+
         // Set the first tuple of intersection
-        
+
         tuple1->x = second->begin.x + t0 * dx2;
         tuple1->y = second->begin.y + t0 * dy2;
-        
+
         // Check to see if the intersection is a single tuple
-        
+
         if (t0 == t1) return 1;
-        
+
         // Otherwise, set the second tuple of intersection as well
-        
+
         tuple2->x = second->begin.x + t1 * dx2;
         tuple2->y = second->begin.y + t1 * dy2;
         return 2;
     }
-    
+
     // The segments are skew and may intersect in a tuple.
     // Get the intersect parameter for the first line
-    
+
     double i1 = (dx2 * wy - dy2 * wx) / dt;
     if (inFirstSegment && (i1 < 0 || i1 > 1)) return 0;
-    
+
     // Get the intersect parameter for the second line
 
@@ -226,4 +226,9 @@
     vertices[3].x = 0;       vertices[3].y = numRows;
 
+    clipLine.begin.x = 0;
+    clipLine.begin.y = 0;
+    clipLine.end.x = 0;
+    clipLine.end.y = 0;
+
     for (i = 0; i < 4 && found < 2; ++i)
     {
@@ -237,5 +242,5 @@
                 ++found;
             }
-            else if (tuple1.x != clipLine.begin.x || 
+            else if (tuple1.x != clipLine.begin.x ||
                      tuple1.y != clipLine.begin.y)
             {
@@ -245,7 +250,7 @@
         }
     }
-    
+
     // If two endpoints are found, clip the line
-    
+
     if (found > 1)
     {
@@ -283,4 +288,9 @@
     vertices[3].x = minX; vertices[3].y = maxY;
 
+    clipLine.begin.x = 0;
+    clipLine.begin.y = 0;
+    clipLine.end.x = 0;
+    clipLine.end.y = 0;
+
     for (i = 0; i < 4 && found < 2; ++i)
     {
@@ -294,5 +304,5 @@
                 ++found;
             }
-            else if (tuple1.x != clipLine.begin.x || 
+            else if (tuple1.x != clipLine.begin.x ||
                      tuple1.y != clipLine.begin.y)
             {
@@ -302,7 +312,7 @@
         }
     }
-    
+
     // If two endpoints are found, clip the line
-    
+
     if (found > 1)
     {
@@ -360,5 +370,5 @@
     @param[out] pixels list of PixelPos pointers corresponding
                        based on the line settings
-    @param[in] line Line to map to pixels   
+    @param[in] line Line to map to pixels
     @param[in] numCols maximum X (columns) for the line
     @param[in] numRows maximum Y (rows) for the line            */
@@ -367,17 +377,16 @@
 {
     Line offsetLine;
-    PixelPos *pixel;
     double slope, xOffset, yOffset, xMid, yMid;
     int x, y, xBegin = numCols, yBegin = numRows, xEnd = 0, yEnd = 0;
 
     // Extract the endpoints
-    
+
     double x1 = line->begin.x;
     double y1 = line->begin.y;
     double x2 = line->end.x;
     double y2 = line->end.y;
-    
+
     // Determine the width and height of the line
-    
+
     double dx = x2 - x1;
     double dy = y2 - y1;
@@ -403,5 +412,5 @@
 
     // Step point by point based on the dominate axis
-    
+
     if (fabs (dx) > fabs (dy))
     {
@@ -411,5 +420,5 @@
         // If line is back to front, reorder endpoints and recompute
         // the line width and height
-        
+
         if (x1 > x2)
         {
@@ -421,10 +430,10 @@
 
         // Compute the slope of the line
-        
+
         slope = dy / dx;
-        
+
         // Compute the x and y offsets for the line width extent
 
-        if (xBegin > xEnd) 
+        if (xBegin > xEnd)
             SwapInt (&xBegin, &xEnd);
         else
@@ -451,5 +460,5 @@
     }
     else
-    {       
+    {
         // -------------------
         // vertical(ish) lines
@@ -457,5 +466,5 @@
         // If line is back to front, reorder endpoints and recompute
         // the line width and height
-        
+
         if (y1 > y2)
         {
@@ -465,9 +474,9 @@
             dy = y2 - y1;
         }
-        
+
         // Compute the slope of the line
-        
+
         slope = dx / dy;
-        
+
         // Compute the x and y offsets for the line width extent
 
@@ -481,5 +490,5 @@
         xMid = x1 + slope * (yBegin - y1);
         xOffset = fabs (halfWidth * dr / dy);
-        
+
         for (y = yBegin; y != yEnd; ++y)
         {
Index: /branches/czw_branch/cleanup/magic/remove/src/Makefile.simple
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/Makefile.simple	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/Makefile.simple	(revision 25158)
@@ -36,9 +36,9 @@
 
 STREAKSFLAGS=-DSTREAKS_COMPRESS_OUTPUT=1
-OPTFLAGS= -g -O2
+OPTFLAGS= -g -O2 -Wall -Werror
 #OPTFLAGS= -g
-CFLAGS=`psmodules-config --cflags` -std=gnu99 ${OPTFLAGS} ${STREAKSFLAGS}
-#CFLAGS=`psmodules-config --cflags` -std=gnu99 ${OPTFLAGS}
-LDFLAGS=`psmodules-config --libs`
+CFLAGS=`psmodules-config --cflags` `pslib-config --cflags` -std=gnu99 ${OPTFLAGS} ${STREAKSFLAGS}
+#CFLAGS=`psmodules-config --cflags` `pslib-config --cflags` -std=gnu99 ${OPTFLAGS}
+LDFLAGS=`psmodules-config --libs` `pslib-config --libs`
 
 PROGRAMS= streaksremove streaksreplace streakscompare streaksrelease isdestreaked
Index: /branches/czw_branch/cleanup/magic/remove/src/isdestreaked.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/isdestreaked.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/isdestreaked.c	(revision 25158)
@@ -18,6 +18,5 @@
     psFits *fits = psFitsOpen(fileName, "r");
     if (!fits) {
-        psError(PS_ERR_UNKNOWN, false, "failed to open fits file: %s\n", fileName);
-        psErrorStackPrint(stderr, "");
+        psErrorStackPrint(stderr, "failed to open fits file: %s\n", fileName);
         exit(PS_EXIT_DATA_ERROR);
     }
@@ -25,6 +24,5 @@
     psMetadata *header = psFitsReadHeader(NULL, fits);
     if (!header) {
-        psError(PS_ERR_IO, false, "failed to read header for: %s", fileName);
-        psErrorStackPrint(stderr, "");
+        psErrorStackPrint(stderr, "failed to read header for: %s", fileName);
         exit(PS_EXIT_DATA_ERROR);
     }
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksastrom.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksastrom.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksastrom.c	(revision 25158)
@@ -93,5 +93,5 @@
     // since the transform already accounts for the chip parity we just use the cell parity
     astrom->xParity = (double) xParityCell;
-    astrom->yParity = (double) yParityCell; 
+    astrom->yParity = (double) yParityCell;
 
     astrom->numCols = numCols;
@@ -135,5 +135,5 @@
 
 void
-cellToChipInt(int *xChip, int *yChip, strkAstrom *astrom, int xCell, int yCell)
+cellToChipInt(unsigned int *xChip, unsigned int *yChip, strkAstrom *astrom, int xCell, int yCell)
 {
     if (astrom->xParity > 0) {
@@ -148,5 +148,5 @@
     }
 }
- 
+
 bool
 SkyToLocal(strkPt *outPt, strkAstrom *astrom, double ra, double dec)
@@ -156,5 +156,4 @@
 
     pmFPA *fpa   = (pmFPA *) astrom->fpa;
-    pmChip *chip = (pmChip *) astrom->chip;
 
     // find the RA,DEC coords of the 0,0 pixel for this chip:
@@ -183,5 +182,4 @@
 
     pmFPA *fpa   = (pmFPA *) astrom->fpa;
-    pmChip *chip = (pmChip *) astrom->chip;
 
     // find the RA,DEC coords of the 0,0 pixel for this chip:
@@ -251,5 +249,5 @@
     pmChip *chip = (pmChip *) astrom->chip;
     pmAstromObj *pt = (pmAstromObj *) astrom->pt;
-    
+
     pt->sky->r = ra;
     pt->sky->d = dec;
@@ -276,5 +274,5 @@
     pmChip *chip = (pmChip *) astrom->chip;
     pmAstromObj *pt = (pmAstromObj *) astrom->pt;
-    
+
     cellToChip(&pt->chip->x, &pt->chip->y, astrom, x, y);
 
@@ -294,5 +292,5 @@
 }
 
- 
+
 static bool
 readAstrometry(streakFiles *sf)
@@ -362,5 +360,5 @@
             break;
         }
-    } 
+    }
     if (!sf->chip) {
         psError(PS_ERR_UNKNOWN, true, "Failed to find chip with data.");
Index: /branches/czw_branch/cleanup/magic/remove/src/streakscompare.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streakscompare.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streakscompare.c	(revision 25158)
@@ -5,5 +5,4 @@
 int main(int argc, char *argv[])
 {
-    long i;
     bool status;
 
@@ -35,5 +34,5 @@
     int numErrors = 0;
     for (int component = 0; component < ncomponents; component++) {
-        if (component && !(psFitsMoveExtNum(file1->fits, 1, true) 
+        if (component && !(psFitsMoveExtNum(file1->fits, 1, true)
                            && psFitsMoveExtNum(file2->fits, 1, true))) {
             streaksExit("failed to advance to next extesion\n", PS_EXIT_DATA_ERROR);
@@ -45,5 +44,5 @@
         psImage *image2 = file2->image;
 
-        // TODO: do more sanity checking. For example check that extname's  (if any) match 
+        // TODO: do more sanity checking. For example check that extname's  (if any) match
         // check for matching image cubes
         if (image1 && image2) {
@@ -68,5 +67,5 @@
                         error = ! isnan(value1) && isnan(value2);
                     }
-                    
+
                     if (error) {
                         numErrors++;
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksextern.h
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksextern.h	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksextern.h	(revision 25158)
@@ -54,5 +54,5 @@
             pixels
 */
-    
+
 extern StreakPixels *streak_on_component(Streaks *streaks, strkAstrom *astrom,
                                          int numCols, int numRows);
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksio.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksio.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksio.c	(revision 25158)
@@ -12,5 +12,5 @@
 // Assumptions about the file structure of non-raw files
 // The 'image' for each file (image, mask weight) is contained in the first
-// extension. 
+// extension.
 
 
@@ -625,5 +625,5 @@
         streaksExit("", PS_EXIT_DATA_ERROR);
     }
- 
+
     bool status;
     in->extname = psMetadataLookupStr(&status, in->header, "EXTNAME");
@@ -654,5 +654,4 @@
             streaksExit("", PS_EXIT_DATA_ERROR);
         }
-        psImage *image = (psImage *) (in->imagecube->data[0]);
     }
     setDataExtent(stage, in, (stage == IPP_STAGE_RAW) && !isMask);
@@ -925,6 +924,4 @@
 replicateOutputs(streakFiles *sfiles)
 {
-    bool status = false;
-
     if (!replicate(sfiles->outImage, sfiles->inImage)) {
         psError(PM_ERR_SYS, false, "failed to replicate outImage.");
@@ -973,5 +970,5 @@
 
         if (!nebSwap(server, in->name, out->name)) {
-            psError(PM_ERR_SYS, true, "failed to swap files for: %s.",
+            psError(PM_ERR_SYS, true, "failed to swap files for %s: %s.",
                 in->name, nebErr(server));
             return false;
@@ -1097,7 +1094,7 @@
 setMaskedToNAN(streakFiles *sfiles, psU32 maskMask, bool printCounts)
 {
-        int maskedPixels = 0;
-        int nandPixels = 0;
-        int nandWeights = 0;
+        long maskedPixels = 0;
+        long nandPixels = 0;
+        long nandWeights = 0;
 
         psImage *image = sfiles->outImage->image;
@@ -1120,5 +1117,5 @@
                 psU32 maskVal;
                 if (sfiles->stage == IPP_STAGE_RAW) {
-                    int xChip, yChip;
+                    unsigned int xChip, yChip;
                     cellToChipInt(&xChip, &yChip, sfiles->astrom, x, y);
                     maskVal = psImageGet(mask, xChip, yChip);
@@ -1144,5 +1141,5 @@
         if (printCounts) {
             psLogMsg(sfiles->program_name, PS_LOG_INFO, "time to NAN mask pixels: %f\n", psTimerClear("NAN_MASKED"));
-            int totalPixels = image->numRows * image->numCols;
+            long totalPixels = image->numRows * image->numCols;
             psLogMsg(sfiles->program_name, PS_LOG_INFO, "pixels:        %10ld\n", totalPixels);
             psLogMsg(sfiles->program_name, PS_LOG_INFO, "masked pixels: %10ld %4.2f%%\n", maskedPixels, 100. * maskedPixels / totalPixels);
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksrelease.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksrelease.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksrelease.c	(revision 25158)
@@ -3,8 +3,4 @@
 static pmConfig *parseArguments(int argc, char **argv);
 static bool readAndCopyToOutput(streakFiles *sf, bool exciseAll);
-static StreakPixels * getStreakPixels(streakFiles *sfiles, Streaks *streaks);
-static void exciseNonWarpedPixels(streakFiles *sfiles, double newMaskValue);
-static bool warpedPixel(streakFiles *sfiles, PixelPos *cellCoord);
-static void excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, double newMaskValue);
 static void writeImages(streakFiles *sf, bool exciseImageCube);
 
@@ -12,6 +8,4 @@
 main(int argc, char *argv[])
 {
-    bool status;
-
     psLibInit(NULL);
     psTimerStart("STREAKSREMOVE");
@@ -25,5 +19,5 @@
     // Values to set for masked pixels
     psU32 maskStreak = 0;           // for the image and weight (usually NAN, MAXINT for integer images)
-    psU32 maskMask = 0;             // value looked up for MASK.STREAK 
+    psU32 maskMask = 0;             // value looked up for MASK.STREAK
 
     // Does true work here?
@@ -216,5 +210,5 @@
         // image data directly from psFits
         readImage(sf->inImage, sf->extnum, sf->stage, false);
-        
+
         // astrom struct is only needed for raw stage, and only the chip to cell parameters are used
         sf->astrom = streakSetAstrometry(sf->astrom, sf->stage, NULL, NULL, false,
@@ -304,5 +298,5 @@
             initValue = NAN;
         } else {
-            // otherwise write it to the output 
+            // otherwise write it to the output
             writeImageCube(sf->outImage, sf->inImage->imagecube, extname, sf->extnum);
             initValue = 0;
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksremove.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksremove.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksremove.c	(revision 25158)
@@ -35,5 +35,5 @@
     // Values to set for masked pixels
     psU32 maskStreak = 0;           // for the image and weight (usually NAN, MAXINT for integer images)
-    psU32 maskMask = 0;             // value looked up for MASK.STREAK 
+    psU32 maskMask = 0;             // value looked up for MASK.STREAK
 
     psString streaksFileName = psMetadataLookupStr(NULL, config->arguments, "STREAKS");
@@ -42,5 +42,5 @@
     Streaks *streaks = readStreaksFile(streaksFileName);
     if (!streaks) {
-        psError(PS_ERR_UNKNOWN, "failed to read streaks file: %s", streaksFileName);
+        psError(PS_ERR_UNKNOWN, false, "failed to read streaks file: %s", streaksFileName);
         streaksExit("", PS_EXIT_PROG_ERROR);
     }
@@ -83,5 +83,5 @@
         psLogMsg("streaksremove", PS_LOG_INFO, "time to compute warped pixels: %f\n", cwp_t);
     }
-    
+
     if (sfiles->stage == IPP_STAGE_RAW) {
         // Except for raw stage, all of our (GPC1) files have one image extension.
@@ -97,6 +97,6 @@
     }
 
-    int totalPixels = 0;
-    int totalStreakPixels = 0;
+    long totalPixels = 0;
+    long totalStreakPixels = 0;
 
     // Iterate through each component of the input (except for raw images there is only one)
@@ -132,5 +132,5 @@
                                                         sfiles->inImage->numRows);
             psLogMsg("streaksremove", PS_LOG_INFO, "time to get streak pixels: %f\n", psTimerClear("GET_STREAK_PIXELS"));
-            
+
             // if this extension contained an image, excise the streaked pixels.
             // otherwise it contained an image cube (video cell) which is handled in the if block
@@ -172,5 +172,5 @@
                 }
 
-            } else { 
+            } else {
                 // this component contains an image cube
                 // For now excise it completely
@@ -215,7 +215,6 @@
 
     if (!replicateOutputs(sfiles)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to replicate output files");
+        psErrorStackPrint(stderr, "failed to replicate output files");
         deleteTemps(sfiles);
-        psErrorStackPrint(stderr, "");
         exit(PS_EXIT_UNKNOWN_ERROR);
     }
@@ -247,5 +246,5 @@
     pmConceptsDone();
     pmModelClassCleanup();
-    streaksNebulousCleanup(); 
+    streaksNebulousCleanup();
     pmConfigDone();
     psLogMsg("streaksremove", PS_LOG_INFO, "time to run streaksremove: %f\n", psTimerClear("STREAKSREMOVE"));
@@ -356,5 +355,5 @@
             true);
     }
-    
+
     if ((argnum = psArgumentGet(argc, argv, "-keepnonwarped"))) {
         psArgumentRemove(argnum, &argc, argv);
@@ -374,5 +373,5 @@
         psArgumentRemove(argnum, &argc, argv);
     }
-        
+
     // if skycells are not provided then we have to execise all pixels  unless -keepnonwarped
     pmConfigFileSetsMD(config->arguments, &argc, argv, "SKYCELLS", "-skycell", "-skycelllist");
@@ -628,5 +627,5 @@
             initValue = NAN;
         } else {
-            // otherwise write it to the output 
+            // otherwise write it to the output
             writeImageCube(sf->outImage, sf->inImage->imagecube, extname, sf->extnum);
             initValue = 0;
@@ -799,63 +798,98 @@
     sFile *out = sfiles->outSources;
 
-    in->header = psFitsReadHeader(NULL, in->fits);
-    if (!in->header) {
-        psError(PS_ERR_IO, false, "failed to read header from %s", in->resolved_name);
+
+    // Primary header, should be "something.hdr"
+    {
+        psMetadata *header = psFitsReadHeader(NULL, in->fits);
+        if (!header) {
+            psError(PS_ERR_IO, false, "failed to read header from %s", in->resolved_name);
+            streaksExit("", PS_EXIT_DATA_ERROR);
+        }
+
+        bool status;
+        psString extname = psMetadataLookupStr(&status, header, "EXTNAME");
+        if (!extname) {
+            psError(PS_ERR_IO, false, "failed to find extname in header of %s", in->resolved_name);
+            streaksExit("", PS_EXIT_DATA_ERROR);
+        }
+        addDestreakKeyword(header);
+
+        if (!psFitsWriteBlank(out->fits, header, extname)) {
+            psError(PS_ERR_IO, false, "failed to write blank in header of %s", in->resolved_name);
+            streaksExit("", PS_EXIT_DATA_ERROR);
+        }
+        psFree(header);
+    }
+
+    // Extension with PSF fits, should be "something.psf"
+    {
+        if (!psFitsMoveExtNum(in->fits, 1, true)) {
+            psErrorStackPrint(stderr, "failed to read header from %s", in->resolved_name);
+            streaksExit("", PS_EXIT_DATA_ERROR);
+        }
+
+        psMetadata *header = psFitsReadHeader(NULL, in->fits);
+        if (!header) {
+            psErrorStackPrint(stderr, "failed to read header from %s", in->resolved_name);
+            streaksExit("", PS_EXIT_DATA_ERROR);
+        }
+        psString extname = psMetadataLookupStr(NULL, header, "EXTNAME");
+        if (!extname) {
+            psError(PS_ERR_IO, false, "failed to find extname in header of %s", in->resolved_name);
+            streaksExit("", PS_EXIT_DATA_ERROR);
+        }
+
+        psArray *inTable = psFitsReadTable(in->fits);
+        if (!inTable->n) {
+            psErrorStackPrint(stderr, "table in %s is empty", in->resolved_name);
+            streaksExit("", PS_EXIT_DATA_ERROR);
+        }
+
+        psArray *outTable = psArrayAllocEmpty(inTable->n);
+        int j = 0;
+        int numCensored = 0;
+        for (int i = 0 ; i < inTable->n; i++) {
+            psMetadata *row = inTable->data[i];
+
+            psF32 x = psMetadataLookupF32(NULL, row, "X_PSF");
+            psF32 y = psMetadataLookupF32(NULL, row, "Y_PSF");
+
+            psU32 mask = psImageGet(maskImage, x, y);
+
+            // Key the source if the center pixel is not masked with maskStreak
+            if (!(mask & maskStreak) ) {
+                psArraySet(outTable, j++, row);
+            } else {
+                numCensored++;
+            }
+        }
+
+        // get rid of unused elements (don't know if this is necessary)
+        psArrayRealloc(outTable, j);
+
+        addDestreakKeyword(header);
+        if (psArrayLength(outTable) > 0) {
+            printf("Censored %d sources\n", numCensored);
+            if (! psFitsWriteTable(out->fits, header, outTable, extname)) {
+                psErrorStackPrint(stderr, "failed to write table to %s", out->resolved_name);
+                streaksExit("", PS_EXIT_DATA_ERROR);
+            }
+        } else {
+            printf("Censored ALL %d sources\n", numCensored);
+            if (! psFitsWriteTableEmpty(out->fits, header, inTable->data[0], extname)) {
+                psErrorStackPrint(stderr, "failed to write empty table to %s", out->resolved_name);
+                streaksExit("", PS_EXIT_DATA_ERROR);
+            }
+        }
+        psFree(header);
+        psFree(outTable);
+        psFree(inTable);
+    }
+
+    // XXX Will need to update to handle extension with extended sources, etc.
+
+    if (!psFitsClose(out->fits)) {
+        psErrorStackPrint(stderr, "failed to close table %s", out->resolved_name);
         streaksExit("", PS_EXIT_DATA_ERROR);
     }
-
-    bool status;
-    psString extname = psMetadataLookupStr(&status, in->header, "EXTNAME");
-    if (!extname) {
-        psError(PS_ERR_IO, false, "failed to find extname in header of %s", in->resolved_name);
-        streaksExit("", PS_EXIT_DATA_ERROR);
-    }
-
-    psArray *inTable = psFitsReadTable(in->fits);
-    if (!inTable->n) {
-        psError(PS_ERR_IO, false, "table in %s is empty", in->resolved_name);
-        streaksExit("", PS_EXIT_DATA_ERROR);
-    }
-
-    psArray *outTable = psArrayAllocEmpty(inTable->n);
-    int j = 0;
-    int numCensored = 0;
-    for (int i = 0 ; i < inTable->n; i++) {
-        psMetadata *row = inTable->data[i];
-
-        psF32 x = psMetadataLookupF32 (&status, row, "X_PSF");
-        psF32 y = psMetadataLookupF32 (&status, row, "Y_PSF");
-        
-        psU32 mask = psImageGet(maskImage, x, y);
-
-        // Key the source if the center pixel is not masked with maskStreak
-        if (! (mask & maskStreak) ) {
-            psArraySet(outTable, j++, row);
-        } else {
-            numCensored++;
-        }
-    }
-
-    // get rid of unused elements (don't know if this is necessary)
-    psArrayRealloc(outTable, j);
-
-    addDestreakKeyword(in->header);
-    if (psArrayLength(outTable) > 0) {
-        printf("Censored %d sources\n", numCensored);
-        if (! psFitsWriteTable(out->fits, in->header, outTable, extname)) {
-            psError(PS_ERR_IO, false, "failed to write table to %s", out->resolved_name);
-            streaksExit("", PS_EXIT_DATA_ERROR);
-        }
-    } else {
-        printf("Censored ALL %d sources\n", numCensored);
-        if (! psFitsWriteTableEmpty(out->fits, in->header, inTable->data[0], extname)) {
-            psError(PS_ERR_IO, false, "failed to write empty table to %s", out->resolved_name);
-            streaksExit("", PS_EXIT_DATA_ERROR);
-        }
-    }
-
-    if (!psFitsClose(out->fits)) {
-        psError(PS_ERR_IO, false, "failed to close table %s", out->resolved_name);
-        streaksExit("", PS_EXIT_DATA_ERROR);
-    }
-}
+}
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksremove.h
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksremove.h	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksremove.h	(revision 25158)
@@ -84,5 +84,5 @@
 // can't declare this in streaksastrom due to header file ordering
 extern void cellToChip(double *xChip, double *yChip, strkAstrom *astrom, double xCell, double yCell);
-extern void cellToChipInt(int *xChip, int *yChip, strkAstrom *astrom, int xCell, int yCell);
+extern void cellToChipInt(unsigned int *xChip, unsigned int *yChip, strkAstrom *astrom, int xCell, int yCell);
 
 extern bool computeWarpedPixels(streakFiles *sf);
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksreplace.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksreplace.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksreplace.c	(revision 25158)
@@ -8,8 +8,5 @@
 int main(int argc, char *argv[])
 {
-    long i;
     bool status;
-    StreakPixels *pixels;
-    PixelPos *pixelPos;
 
     psLibInit(NULL);
@@ -92,6 +89,5 @@
 
     if (!replicateOutputs(sfiles)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to replicate output files");
-        psErrorStackPrint(stderr, "");
+        psErrorStackPrint(stderr, "failed to replicate output files");
         exit(PS_EXIT_UNKNOWN_ERROR);
     }
@@ -172,5 +168,5 @@
             true);
     }
-    
+
     bool gotMask = false;
     if ((argnum = psArgumentGet(argc, argv, "-mask"))) {
@@ -353,5 +349,5 @@
         // we have an image cube
         double initValue;
-        // otherwise write it to the output 
+        // otherwise write it to the output
         writeImageCube(sf->outImage, sf->recImage->imagecube, extname, sf->extnum);
 
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksutil.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksutil.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksutil.c	(revision 25158)
@@ -44,5 +44,5 @@
 // we just bail out
 void streaksExit(psString str, int exitCode) {
-    psErrorStackPrint(stderr, str);
+    psErrorStackPrint(stderr, "%s", str);
     if (ourStreakFiles) {
         deleteTemps(ourStreakFiles);
Index: /branches/czw_branch/cleanup/magic/remove/src/warpedpixels.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/warpedpixels.c	(revision 25157)
+++ /branches/czw_branch/cleanup/magic/remove/src/warpedpixels.c	(revision 25158)
@@ -23,5 +23,5 @@
 
     psRegion     *bounds = pmChipPixels(sf->chip);
-    
+
     int width  = bounds->x1 - bounds->x0;
     int height = bounds->y1 - bounds->y0;
@@ -83,5 +83,5 @@
 
     /* now set up our wrapper to the chip astrometry to apply to the whole chip */
-    sf->astrom = streakSetAstrometry(sf->astrom, sf->stage, sf->inAstrom->fpa, sf->chip, false, NULL, 
+    sf->astrom = streakSetAstrometry(sf->astrom, sf->stage, sf->inAstrom->fpa, sf->chip, false, NULL,
         sf->warpedPixels->numCols, sf->warpedPixels->numRows);
 
@@ -106,5 +106,5 @@
         // convert corner of skycell to sky coordinates
         if (!pmAstromWCStoSky(&sky, wcs, &pt[i])) {
-            psError(PS_ERR_IO, false, "failed to convert pt %d of %s to sky coords: %s", fileName);
+            psErrorStackPrint(stderr, "failed to convert pt %d of %s to sky coords", i, fileName);
             streaksExit("", PS_EXIT_DATA_ERROR);
         }
@@ -112,5 +112,5 @@
         // convert to chip coordinates
         if (!skyToCell(&p, sf->astrom, sky.r, sky.d)) {
-            psError(PS_ERR_IO, false, "failed to convert pt %d of %s to sky coords: %s", fileName);
+            psErrorStackPrint(stderr, "failed to convert pt %d of %s to sky coords", i, fileName);
             streaksExit("", PS_EXIT_DATA_ERROR);
         }
@@ -171,5 +171,5 @@
 }
 
-// x as a function of y for the line between two points 
+// x as a function of y for the line between two points
 // Note: the caller guarentees that the y's of the two points are different
 static double xOfY(psPlane *pI, psPlane *pJ, int y)
@@ -212,5 +212,5 @@
  * To compute the overlap of a quadrilateral with a set of
  * points we transform the 4 corners to image coordinates
- * and name the 4 points of the quad 
+ * and name the 4 points of the quad
             pt 0 is left most (bottom most corner)
             pt 1 is bottom most (right most corner)
@@ -238,5 +238,5 @@
 
                 3
-                 C       
+                 C
          ---------------2           left boundary:  line 0_1 y < pt0.y
                  B                                  line 0_3 y >= pt0.y
@@ -249,5 +249,5 @@
               C
         0----------------
-              B     
+              B
       ----------------2
               A
@@ -258,5 +258,5 @@
 
         3       2
-            
+
             B
 
@@ -265,8 +265,8 @@
 (region A and C are empty in the case where the points form a rectangle)
 */
-            
+
 /*
     Name the corners
-    The following algorithm works for points that form a quadrilateral 
+    The following algorithm works for points that form a quadrilateral
     I think it also works for the situation where 3 points are co-linear
     and we have a triangle, but that isn't important for our purposes
@@ -313,5 +313,5 @@
         pt[i] = pt[i+1];
     }
-            
+
     // now find the right most (top most) of the remaining 2 points
     if ((pt[0].x > pt[1].x) ||
Index: /branches/czw_branch/cleanup/ppMops/src/ppMops.c
===================================================================
--- /branches/czw_branch/cleanup/ppMops/src/ppMops.c	(revision 25157)
+++ /branches/czw_branch/cleanup/ppMops/src/ppMops.c	(revision 25158)
@@ -6,7 +6,7 @@
 int main(int argc, char *argv[])
 {
-    if (argc != 7) {
+    if (argc != 6) {
         fprintf(stderr, "Insufficient arguments.\n");
-        fprintf(stderr, "Usage: %s DETECTIONS ZP EXP_ID EXP_NAME DIRECTION OUTPUT\n", argv[0]);
+        fprintf(stderr, "Usage: %s DETECTIONS ZP EXP_ID EXP_NAME OUTPUT\n", argv[0]);
         exit(PS_EXIT_CONFIG_ERROR);
     }
@@ -17,6 +17,5 @@
     data->exp_id = atoll(argv[3]);
     data->exp_name = psStringCopy(argv[4]);
-    data->direction = atoi(argv[5]);
-    data->output = psStringCopy(argv[6]);
+    data->output = psStringCopy(argv[5]);
 
     if (!isfinite(data->zp)) {
@@ -129,4 +128,5 @@
                                         psMetadataLookupF32(NULL, header, "FWHM_MIN"));
 
+
         psMetadataAddStr(outHeader, PS_LIST_TAIL, "RA", 0, "Right ascension of boresight", ra);
         psMetadataAddStr(outHeader, PS_LIST_TAIL, "DEC", 0, "Declination of boresight", dec);
@@ -141,10 +141,9 @@
         psMetadataAddStr(outHeader, PS_LIST_TAIL, "FPA_ID", 0, "Exposure name", data->exp_name);
         psMetadataAddS64(outHeader, PS_LIST_TAIL, "EXP_ID", 0, "Exposure identifier", data->exp_id);
-        psMetadataAddBool(outHeader, PS_LIST_TAIL, "POSITIVE", 0, "Positive subtraction?", data->direction);
         psMetadataAddStr(outHeader, PS_LIST_TAIL, "OBSCODE", 0, "IAU Observatory code", OBSERVATORY_CODE);
         psMetadataAddF32(outHeader, PS_LIST_TAIL, "STARPSF", 0, "Stellar PSF (arcsec)", psf);
 
         // These are completely fake
-        psMetadataAddF32(outHeader, PS_LIST_TAIL, "LIMITMAG", 0, "Limiting magnitude (FAKE)", 99.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "LIMITMAG", 0, "Limiting magnitude (FAKE)", 25.0);
         psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE1", 0, "Detection efficiency (FAKE)", 0.0);
         psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE2", 0, "Detection efficiency (FAKE)", 0.0);
Index: /branches/czw_branch/cleanup/ppMops/src/ppMops.h
===================================================================
--- /branches/czw_branch/cleanup/ppMops/src/ppMops.h	(revision 25157)
+++ /branches/czw_branch/cleanup/ppMops/src/ppMops.h	(revision 25158)
@@ -16,5 +16,6 @@
     psString detections;                // Detections filename
     float zp;                           // Magnitude zero point
-    bool direction;                     // Direction of subtraction, 1=positive, 0=negative
+    psS64 exp_id;                       // Exposure identifier
+    psString exp_name;                  // Exposure name
     psString output;                    // Output filename
 } ppMopsData;
Index: /branches/czw_branch/cleanup/ppMops/src/ppMopsData.c
===================================================================
--- /branches/czw_branch/cleanup/ppMops/src/ppMopsData.c	(revision 25157)
+++ /branches/czw_branch/cleanup/ppMops/src/ppMopsData.c	(revision 25158)
@@ -11,4 +11,5 @@
 {
     psFree(data->detections);
+    psFree(data->exp_name);
     psFree(data->output);
     return;
@@ -22,4 +23,6 @@
     data->detections = NULL;
     data->zp = NAN;
+    data->exp_id = 0;
+    data->exp_name = NULL;
     data->output = NULL;
 
Index: /branches/czw_branch/cleanup/ppStack/src/ppStackCombineFinal.c
===================================================================
--- /branches/czw_branch/cleanup/ppStack/src/ppStackCombineFinal.c	(revision 25157)
+++ /branches/czw_branch/cleanup/ppStack/src/ppStackCombineFinal.c	(revision 25158)
@@ -56,4 +56,7 @@
         }
         psKernel *covar = options->covariances->data[i]; // Covariance matrix
+        if (!covar) {
+            continue;
+        }
         float weight = options->weightings->data.F32[i]; // Weight to apply
         psBinaryOp(covar->image, covar->image, "*", psScalarAlloc(weight, PS_TYPE_F32));
Index: /branches/czw_branch/cleanup/psLib/src/fits/psFitsHeader.c
===================================================================
--- /branches/czw_branch/cleanup/psLib/src/fits/psFitsHeader.c	(revision 25157)
+++ /branches/czw_branch/cleanup/psLib/src/fits/psFitsHeader.c	(revision 25158)
@@ -50,5 +50,5 @@
 
 // List of the start of FITS header keys not to write (handled by cfitsio); NULL-terminated
-static const char *noWriteFitsKeyStarts[] = { "NAXIS", "TTYPE", "TFORM", NULL };
+static const char *noWriteFitsKeyStarts[] = { "NAXIS", "TTYPE", "TFORM", "TZERO", "TSCAL", NULL };
 
 // List of compressed FITS header keys not to write (handled by cfitsio); NULL-terminated
@@ -305,4 +305,5 @@
                 keyType = 'C';
             }
+            psTrace("psLib.fits", 3, "Reading keyword %s, type %c\n", keyName, keyType);
             if (status != 0) {
                 break;
@@ -327,6 +328,12 @@
                                                -INFINITY);
                 } else {
-                    success = psMetadataAddS32(header, PS_LIST_TAIL, keyNameTrans, dupFlag, keyComment,
-                                               atoi(keyValue));
+                    long long value = atoll(keyValue); // Value
+                    if (value > PS_MIN_S32 && value < PS_MAX_S32) {
+                        success = psMetadataAddS32(header, PS_LIST_TAIL, keyNameTrans, dupFlag, keyComment,
+                                                   value);
+                    } else {
+                        success = psMetadataAddS64(header, PS_LIST_TAIL, keyNameTrans, dupFlag, keyComment,
+                                                   value);
+                    }
                 }
                 break;
@@ -509,16 +516,10 @@
         psMetadataItem *simpleItem = psMetadataLookup(output, "SIMPLE"); // SIMPLE in the header
         if (simpleItem) {
-            if (simpleItem->type != PS_DATA_BOOL) {
-                psError(PS_ERR_BAD_PARAMETER_TYPE, true, "SIMPLE in a FITS header must be of boolean type: "
-                        "not %x --- assuming FALSE.\n", simpleItem->type);
+            if (simpleItem->type != PS_DATA_BOOL || !simpleItem->data.B) {
                 int value = false;          // Temporary holder for boolean
+                psWarning("Writing SIMPLE=F to FITS header by request");
                 fits_update_key(fits->fd, TLOGICAL, "SIMPLE", &value,
                                 "File does not conform to FITS standard", &status);
                 simple = false;
-            } else if (!simpleItem->data.B) {
-                simple = false;
-                int value = false;      // Temporary holder for boolean
-                fits_update_key(fits->fd, TLOGICAL, "SIMPLE", &value,
-                                "File does not conform to FITS standard", &status);
             }
             // Uncompressed SIMPLE = T is taken care of by cfitsio.
@@ -546,4 +547,5 @@
             char comment[FLEN_CARD];    // Comment for ZIMAGE; unused
             int value;                  // Value for ZIMAGE; unused
+            psTrace("psLib.fits", 3, "Writing header ZSIMPLE to preserve PHU");
             fits_read_key(fits->fd, TLOGICAL, "ZIMAGE", &value, comment, &status);
             fits_insert_key_log(fits->fd, "ZSIMPLE", simple, "Uncompressed file's conforms to FITS", &status);
@@ -575,8 +577,10 @@
                 if (keywordInList(name, noWriteCompressedKeys) ||
                     (keyStarts && keywordStartsWith(name, noWriteCompressedKeyStarts))) {
+                    psTrace("psLib.fits", 3, "Not writing FITS keyword %s", name);
                     continue;
                 }
             } else if (keywordInList(name, noWriteCompressedKeys) ||
                        (keyStarts && keywordStartsWith(name, noWriteCompressedKeyStarts))) {
+                psTrace("psLib.fits", 3, "Not writing FITS keyword %s", name);
                 continue;
             }
@@ -584,4 +588,5 @@
             if (keywordInList(name, noWriteFitsKeys) ||
                 (keyStarts && keywordStartsWith(name, noWriteFitsKeyStarts))) {
+                psTrace("psLib.fits", 3, "Not writing FITS keyword %s", name);
                 continue;
             }
@@ -592,4 +597,5 @@
                 psWarning("COMMENT header is not of type STRING (%x) --- ignored.", item->type);
             } else {
+                psTrace("psLib.fits", 5, "Writing header COMMENT: %s", item->data.str);
                 fits_write_comment(fits->fd, item->data.str, &status);
             }
@@ -598,4 +604,5 @@
                 psWarning("COMMENT header is not of type STRING (%x) --- ignored.", item->type);
             } else {
+                psTrace("psLib.fits", 5, "Writing header HISTORY: %s", item->data.str);
                 fits_write_history(fits->fd, item->data.str, &status);
             }
@@ -605,28 +612,36 @@
               case PS_DATA_BOOL: {
                   int value = item->data.B;
+                  psTrace("psLib.fits", 5, "Writing BOOL header %s: %d", name, value);
                   fits_update_key(fits->fd, TLOGICAL, name, &value, item->comment, &status);
                   break;
               }
               case PS_DATA_S8:
+                psTrace("psLib.fits", 5, "Writing S8 header %s: %d", name, (int)item->data.S8);
                 fits_update_key(fits->fd, TBYTE, name, &item->data.S8, item->comment, &status);
                 break;
               case PS_DATA_S16:
+                psTrace("psLib.fits", 5, "Writing S16 header %s: %d", name, (int)item->data.S16);
                 fits_update_key(fits->fd, TSHORT, name, &item->data.S16, item->comment, &status);
                 break;
               case PS_DATA_S32:
+                psTrace("psLib.fits", 5, "Writing S32 header %s: %d", name, (int)item->data.S32);
                 fits_update_key(fits->fd, TINT, name, &item->data.S32, item->comment, &status);
                 break;
               case PS_DATA_S64:
+                psTrace("psLib.fits", 5, "Writing S64 header %s: %" PRId64, name, item->data.S64);
                 fits_update_key(fits->fd, TLONGLONG, name, &item->data.S64, item->comment, &status);
                 break;
               case PS_DATA_U8: {
                   unsigned short int temp = item->data.U8;
+                psTrace("psLib.fits", 5, "Writing U8 header %s: %d", name, (int)item->data.U8);
                   fits_update_key(fits->fd, TUSHORT, name, &temp, item->comment, &status);
                   break;
               }
               case PS_DATA_U16:
+                psTrace("psLib.fits", 5, "Writing U16 header %s: %d", name, (int)item->data.U16);
                 fits_update_key(fits->fd, TUSHORT, name, &item->data.U16, item->comment, &status);
                 break;
               case PS_DATA_U32:
+                psTrace("psLib.fits", 5, "Writing U32 header %s: %d", name, (unsigned int)item->data.U32);
                 fits_update_key(fits->fd, TUINT, name, &item->data.U32, item->comment, &status);
                 break;
@@ -639,8 +654,10 @@
                 }
                 psS64 temp = item->data.U64; // Signed version
+                psTrace("psLib.fits", 5, "Writing U64 header %s: %" PRIu64, name, item->data.U64);
                 fits_update_key(fits->fd, TLONGLONG, name, &temp, item->comment, &status);
                 break;
               case PS_DATA_F32: {
                   int infCheck = 0;         // Result of isinf()
+                  psTrace("psLib.fits", 5, "Writing F32 header %s: %f", name, item->data.F32);
                   if (isnan(item->data.F32)) {
                       fits_update_key(fits->fd, TSTRING, name, "NaN", item->comment, &status);
@@ -659,4 +676,5 @@
               case PS_DATA_F64: {
                   int infCheck = 0;         // Result of isinf()
+                  psTrace("psLib.fits", 5, "Writing F32 header %s: %lf", name, item->data.F64);
                   if (isnan(item->data.F64)) {
                       fits_update_key(fits->fd, TSTRING, name, "NaN", item->comment, &status);
@@ -674,4 +692,5 @@
               }
               case PS_DATA_STRING:
+                psTrace("psLib.fits", 5, "Writing STR header %s: %s", name, item->data.str);
                 fits_update_key(fits->fd, TSTRING, name, item->data.V, item->comment, &status);
                 break;
Index: /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionAnalysis.c
===================================================================
--- /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionAnalysis.c	(revision 25157)
+++ /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionAnalysis.c	(revision 25158)
@@ -42,5 +42,6 @@
         psFree(subRegion);
 
-        psMetadataAddStr(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, PS_META_DUPLICATE_OK,
+        psMetadataAddPtr(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION,
+                         PS_DATA_REGION | PS_META_DUPLICATE_OK,
                          "Region over which subtraction was performed", string);
         psFree(string);
Index: /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionAnalysis.h
===================================================================
--- /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionAnalysis.h	(revision 25157)
+++ /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionAnalysis.h	(revision 25158)
@@ -27,4 +27,5 @@
 bool pmSubtractionAnalysis(
     psMetadata *analysis,               ///< Metadata container for QA information
+    psMetadata *header,                 ///< Metadata container for QA information to put in header
     pmSubtractionKernels *kernels,      ///< Kernels
     psRegion *region,                   ///< Region for subtraction
Index: /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionMatch.c
===================================================================
--- /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionMatch.c	(revision 25157)
+++ /branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionMatch.c	(revision 25158)
@@ -10,4 +10,5 @@
 #include "pmHDU.h"
 #include "pmFPA.h"
+#include "pmHDUUtils.h"
 #include "pmSubtractionParams.h"
 #include "pmSubtractionKernels.h"
@@ -58,16 +59,16 @@
 
 
-static bool getStamps(pmSubtractionStampList **stamps, // Stamps to read
-                      const pmReadout *ro1, // Readout 1
-                      const pmReadout *ro2, // Readout 2
-                      const psImage *subMask, // Mask for subtraction, or NULL
-                      psImage *variance,  // Variance map
-                      const psRegion *region, // Region of interest, or NULL
-                      float thresh1,  // Threshold for stamp finding on readout 1
-                      float thresh2,  // Threshold for stamp finding on readout 2
-                      float stampSpacing, // Spacing between stamps
-                      int size,         // Kernel half-size
-                      int footprint,     // Convolution footprint for stamps
-                      pmSubtractionMode mode // Mode for subtraction
+static bool subtractionGetStamps(pmSubtractionStampList **stamps, // Stamps to read
+                                 const pmReadout *ro1, // Readout 1
+                                 const pmReadout *ro2, // Readout 2
+                                 const psImage *subMask, // Mask for subtraction, or NULL
+                                 psImage *variance,  // Variance map
+                                 const psRegion *region, // Region of interest, or NULL
+                                 float thresh1,  // Threshold for stamp finding on readout 1
+                                 float thresh2,  // Threshold for stamp finding on readout 2
+                                 float stampSpacing, // Spacing between stamps
+                                 int size,         // Kernel half-size
+                                 int footprint,     // Convolution footprint for stamps
+                                 pmSubtractionMode mode // Mode for subtraction
     )
 {
@@ -163,4 +164,31 @@
 }
 
+static void subtractionAnalysisUpdate(pmReadout *conv1, pmReadout *conv2, // Convolved images
+                                      const psMetadata *analysis, // Analysis metadata
+                                      const psMetadata *header // Header metadata
+    )
+{
+    if (conv1) {
+        conv1->analysis = psMetadataCopy(conv1->analysis, analysis);
+    }
+    if (conv2) {
+        conv2->analysis = psMetadataCopy(conv2->analysis, analysis);
+    }
+
+    if (conv1 && conv1->parent) {
+        pmHDU *hdu = pmHDUFromCell(conv1->parent);
+        if (hdu) {
+            hdu->header = psMetadataCopy(hdu->header, header);
+        }
+    }
+    if (conv2 && conv2->parent) {
+        pmHDU *hdu = pmHDUFromCell(conv2->parent);
+        if (hdu) {
+            hdu->header = psMetadataCopy(hdu->header, header);
+        }
+    }
+
+    return;
+}
 
 
@@ -253,4 +281,5 @@
 
     psMetadata *outAnalysis = psMetadataAlloc(); // Output analysis values
+    psMetadata *outHeader = psMetadataAlloc(); // Output header values
 
     psTrace("psModules.imcombine", 2, "Convolving...\n");
@@ -259,7 +288,9 @@
         psRegion *region = regions->data[i]; // Region of interest
 
-        if (!pmSubtractionAnalysis(outAnalysis, kernel, region, ro1->image->numCols, ro1->image->numRows)) {
+        if (!pmSubtractionAnalysis(outAnalysis, outHeader, kernel, region,
+                                   ro1->image->numCols, ro1->image->numRows)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to generate QA data");
             psFree(outAnalysis);
+            psFree(outHeader);
             psFree(subMask);
             psFree(kernels);
@@ -272,4 +303,5 @@
             psError(PS_ERR_UNKNOWN, false, "Unable to convolve image.");
             psFree(outAnalysis);
+            psFree(outHeader);
             psFree(subMask);
             psFree(kernels);
@@ -283,11 +315,7 @@
     psFree(regions);
 
-    if (conv1) {
-        psMetadataCopy(conv1->analysis, outAnalysis);
-    }
-    if (conv2) {
-        psMetadataCopy(conv2->analysis, outAnalysis);
-    }
+    subtractionAnalysisUpdate(conv1, conv2, outAnalysis, outHeader);
     psFree(outAnalysis);
+    psFree(outHeader);
 
     return true;
@@ -369,4 +397,5 @@
     pmSubtractionKernels *kernels = NULL; // Kernel basis functions
     psMetadata *analysis = psMetadataAlloc(); // QA data
+    psMetadata *header = psMetadataAlloc(); // QA data for header
 
     int numCols = ro1->image->numCols, numRows = ro1->image->numRows; // Image dimensions
@@ -442,5 +471,5 @@
             // We get the stamps here; we will also attempt to get stamps at the first iteration, but it
             // doesn't matter.
-            if (!getStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2,
+            if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2,
                            stampSpacing, size, footprint, subMode)) {
                 goto MATCH_ERROR;
@@ -508,6 +537,7 @@
                 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Iteration %d.", k);
 
-                if (!getStamps(&stamps, ro1, ro2, subMask, variance, region, stampThresh1, stampThresh2,
-                               stampSpacing, size, footprint, subMode)) {
+                if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region,
+                                          stampThresh1, stampThresh2, stampSpacing,
+                                          size, footprint, subMode)) {
                     goto MATCH_ERROR;
                 }
@@ -569,5 +599,5 @@
             memCheck("solution");
 
-            if (!pmSubtractionAnalysis(analysis, kernels, region, numCols, numRows)) {
+            if (!pmSubtractionAnalysis(analysis, header, kernels, region, numCols, numRows)) {
                 psError(PS_ERR_UNKNOWN, false, "Unable to generate QA data");
                 goto MATCH_ERROR;
@@ -605,11 +635,7 @@
     memCheck("convolution");
 
-    if (conv1) {
-        psMetadataCopy(conv1->analysis, analysis);
-    }
-    if (conv2) {
-        psMetadataCopy(conv2->analysis, analysis);
-    }
+    subtractionAnalysisUpdate(conv1, conv2, analysis, header);
     psFree(analysis);
+    psFree(header);
 
 #ifdef TESTING
@@ -633,4 +659,5 @@
 MATCH_ERROR:
     psFree(analysis);
+    psFree(header);
     psFree(region);
     psFree(regionString);
Index: /branches/czw_branch/cleanup/pstamp/scripts/pstamp_finish.pl
===================================================================
--- /branches/czw_branch/cleanup/pstamp/scripts/pstamp_finish.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/pstamp/scripts/pstamp_finish.pl	(revision 25158)
@@ -94,5 +94,5 @@
         if (!mkdir $out_dir) {
             print STDERR "cannot create output directory $out_dir";
-            stop_request_and_exit($req_id, $PS_EXIT_UNKNOWN_ERROR);
+            stop_request($req_id, $PS_EXIT_UNKNOWN_ERROR);
         }
 
@@ -102,10 +102,10 @@
         # request
         print STDERR "output directory $out_dir exists but is not a directory";
-        stop_request_and_exit($req_id, $PS_EXIT_UNKNOWN_ERROR);
+        stop_request($req_id, $PS_EXIT_UNKNOWN_ERROR);
     }
 
     if (! -e $req_file ) {
         print STDERR "request file $req_file is missing\n";
-        stop_request_and_exit($req_id, $PS_EXIT_CONFIG_ERROR);
+        stop_request($req_id, $PS_EXIT_CONFIG_ERROR);
     }
 
@@ -117,5 +117,5 @@
         # point 
         print STDERR "failed to read request_file $req_file" ;
-        stop_request_and_exit($req_id, $PS_EXIT_CONFIG_ERROR);
+        stop_request($req_id, $PS_EXIT_CONFIG_ERROR);
     }
 
@@ -154,6 +154,14 @@
                 print STDERR "Request $req_id produced no jobs.\n"
             }
-            # This should not happen. A fake job should be queued
-            stop_request_and_exit($req_id, $PS_EXIT_PROG_ERROR);
+            # No Jobs. 
+            # XXXX Ouch. We need results for each rownum (each request specification) in the request file 
+            # including those that produced no jobs.
+            # for now add an entry for rownum 1 and a phony error code.
+            # we've included parse_error.txt to the fileset if it exists
+            #
+            my $rownum = 0;
+            my $fault = 42; # get a real error code
+            print $tdf "$rownum|$fault|0|0|";
+            print $tdf "0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|\n";
         } else {
             my $metadata = $mdcParser->parse($output) or die("Unable to parse metdata config doc");
@@ -174,11 +182,4 @@
         my $exp_id = $job->{exp_id};
 
-        if ($fault eq $PSTAMP_DUP_REQUEST) {
-            # this request had a duplicate request name. We can't put the results
-            # on the data store since the product name is already used
-            # maybe we could be more clever about this and choose a fileset name
-            stop_request_and_exit($req_id, $fault);
-        }
-
         my ($row, $req_info, $project) = get_request_info($rows, $rownum);
 
@@ -188,5 +189,5 @@
             carp("failed to find imagedb for project: $project");
             if (!$fault) {
-                stop_request_and_exit($req_id, $PS_EXIT_CONFIG_ERROR);
+                stop_request($req_id, $PS_EXIT_CONFIG_ERROR);
             }
         }
@@ -279,5 +280,5 @@
 }
 
-sub stop_request_and_exit {
+sub stop_request {
     my $req_id = shift;
     my $fault  = shift;
Index: /branches/czw_branch/cleanup/pstamp/scripts/pstamp_job_run.pl
===================================================================
--- /branches/czw_branch/cleanup/pstamp/scripts/pstamp_job_run.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/pstamp/scripts/pstamp_job_run.pl	(revision 25158)
@@ -11,4 +11,5 @@
 use Sys::Hostname;
 use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Carp;
 use File::Basename;
 use Digest::MD5::File qw( file_md5_hex );
@@ -137,5 +138,5 @@
     }
 } elsif ($jobType eq "get_image") {
-    my_die( "get_image jobs not working right now", $job_id, $PS_EXIT_CONFIG_ERROR);
+    my_die( "get_image jobs not working right now", $job_id, $PS_EXIT_PROG_ERROR);
 
     my $uri = "";
Index: /branches/czw_branch/cleanup/pstamp/scripts/pstamp_parser_run.pl
===================================================================
--- /branches/czw_branch/cleanup/pstamp/scripts/pstamp_parser_run.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/pstamp/scripts/pstamp_parser_run.pl	(revision 25158)
@@ -200,4 +200,6 @@
     unlink $error_file_name if (-e $error_file_name);
 
+    # Run the parser
+
     my $command = "$parse_cmd";
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
Index: /branches/czw_branch/cleanup/pstamp/scripts/pstampparse.pl
===================================================================
--- /branches/czw_branch/cleanup/pstamp/scripts/pstampparse.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/pstamp/scripts/pstampparse.pl	(revision 25158)
@@ -14,5 +14,4 @@
 use PS::IPP::PStamp::Job qw( :standard );
 use File::Temp qw(tempfile);
-use Carp;
 
 my $verbose;
@@ -97,12 +96,10 @@
 my_die("wrong EXTVER $extver found in $request_file_name", $PS_EXIT_PROG_ERROR) if ($extver ne "1");
 
-# check for duplicate request name
-if (!$no_update) {
+{
     my $command = "$pstamptool -listreq  -name $req_name";
     $command .= " -dbname $dbname" if $dbname;
     $command .= " -dbserver $dbserver" if $dbserver;
-    # no verbose so that error message about request not found doesn't appear in parse_error.txt
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-        run(command => $command, verbose => 0);
+        run(command => $command, verbose => $verbose);
     my $exitStatus = $error_code >> 8;
     if ($success) {
@@ -186,6 +183,4 @@
 
     my $option_mask= $row->{OPTION_MASK};
-    my $inverse = ($option_mask & $PSTAMP_SELECT_INVERSE) ? 1 : 0;
-    $row->{inverse} = $inverse;
 
     my $skycenter = $row->{skycenter} = ! ($row->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS);
@@ -252,11 +247,9 @@
         next;
     } else {
-        # Call PS::IPP::PStamp::Job locate_images subroutine to get the images for this
+        # Call PS::IPP::PStamp::Job's locate_images subroutine to get the parameters for this
         # request specification. An array reference is returned.
         my ($x, $y);
-
         $imageList = locate_images($ipprc, $image_db, $req_type, $stage, $id, $search_component,
-                $inverse, $skycenter, $x, $y, $mjd_min, $mjd_max, $filter, $verbose);
-
+                $skycenter, $x, $y, $mjd_min, $mjd_max, $filter, $verbose);
         if (!$imageList or !@$imageList) {
             print STDERR "no matching images found for row $rownum\n" if $verbose;
@@ -289,9 +282,14 @@
     my $have_skycells = shift;
     my $need_magic = shift;
-    my $num_jobs = 0;
 
     my $rownum = $row->{ROWNUM};
 
     my $components = $row->{components};
+    my $numComponents = scalar keys %$components;
+    if ( $numComponents == 0 ) {
+        print STDERR "no jobs for row $rownum\n" if $verbose;
+        insertFakeJobForRow($row, 1, $PSTAMP_NO_JOBS_QUEUED);
+        return 1;
+    }
 
     my $roi_string;
@@ -374,15 +372,14 @@
         my $fault = 0;
 
-        if (($stage ne 'stack') and ($stage ne 'raw')) {
-            if (($image->{state} eq 'goto_purged') or ($image->{data_state} eq 'purged')) {
-                $newState = 'stop';
-                $fault = $PSTAMP_GONE;
-            } elsif (($image->{data_state} ne 'full') or ($image->{state} ne 'full' )) {
-                # XXX here is where we need to queue an update job
-                # for now just say that the image is not available
-                $newState = 'stop';
-                $fault = $PSTAMP_NOT_AVAILABLE;
-            }
-        }
+if (0) {
+        # XXX this doesn't work because not all ippTools outputs include data_state
+        # fix chipTool also need to not make this test for raw stage
+        if ((($stage ne 'stack') and ($image->{data_state} ne 'full')) or $image->{state} ne 'full' ){
+            # XXX here is where we need to queue an update job
+            # for now just say that the image is not available
+            $newState = 'stop';
+            $fault = 49;
+        }
+}
 
         $num_jobs++;
@@ -412,9 +409,4 @@
             print "skipping command: $command\n";
         }
-    }
-    if ( $num_jobs == 0 ) {
-        print STDERR "no jobs for row $rownum\n" if $verbose;
-        insertFakeJobForRow($row, 1, $PSTAMP_NO_OVERLAP);
-        $num_jobs = 1;
     }
     return $num_jobs;
@@ -624,5 +616,4 @@
     return 0 if ($r1->{IMG_TYPE} ne $r2->{IMG_TYPE});
     return 0 if ($r1->{ID} ne $r2->{ID});
-    return 0 if ($r1->{inverse} ne $r2->{inverse});
 
     if (defined($r1->{COMPONENT})) {
Index: /branches/czw_branch/cleanup/pstamp/src/pstamp.h
===================================================================
--- /branches/czw_branch/cleanup/pstamp/src/pstamp.h	(revision 25157)
+++ /branches/czw_branch/cleanup/pstamp/src/pstamp.h	(revision 25158)
@@ -8,7 +8,4 @@
 #include "pslib.h"
 #include "psmodules.h"
-// #include "psphot.h"
-// #include "psastro.h"
-// #include "ppStats.h"
 #include "pstampErrorCodes.h"
 
@@ -31,4 +28,22 @@
 } pspMode;
 
+// error codes returned to users in results flie
+// These must match the values in  PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm
+typedef enum {
+        PSTAMP_SUCCESS          = 0,
+	PSTAMP_SYSTEM_ERROR     = 10,
+	PSTAMP_NOT_IMPLEMENTED  = 11,
+	PSTAMP_UNKNOWN_ERROR    = 12,
+	PSTAMP_DUP_REQUEST      = 20,
+	PSTAMP_INVALID_REQUEST  = 21,
+	PSTAMP_UNKNOWN_PRODUCT  = 22,
+	PSTAMP_NO_IMAGE_MATCH   = 23,
+	PSTAMP_NOT_DESTREAKED   = 24,
+	PSTAMP_NOT_AVAILABLE    = 25,
+	PSTAMP_GONE             = 26,
+	PSTAMP_NO_JOBS_QUEUED   = 27
+} pstampJobErrors;
+
+
 #define PSTAMP_SELECT_IMAGE  1
 #define PSTAMP_SELECT_MASK   2
@@ -44,3 +59,5 @@
 #define STAMP_RESULTS_VERSION "1"
 
+
+
 #endif
Index: /branches/czw_branch/cleanup/pstamp/src/pstampdump.c
===================================================================
--- /branches/czw_branch/cleanup/pstamp/src/pstampdump.c	(revision 25157)
+++ /branches/czw_branch/cleanup/pstamp/src/pstampdump.c	(revision 25158)
@@ -1,7 +1,7 @@
-// pstampdump  - read a fits table describing a postage stamp request or response file and
+// pstampdump  - read a fits file  containing a postage stamp request or response table and
 //               print the contents to stdout
 //
-//              Actually should work for any kind of fits table, but I'm not sure what will
-//              happen for binary data.
+//              Actually this should work fine for dumping the rows of any of any kind of fits table
+//              The -header option is pstamp table specific
 
 #include <pslib.h>
@@ -9,22 +9,35 @@
 #include <string.h>
 
-static psArray *readRequestTable(psString fileName)
+static bool readFitsFile(psString fileName, psMetadata **pHeader, psArray **pTable)
 {
-    psFits *fitsFile = psFitsOpen(fileName, "r");
-    if (fitsFile == NULL) {
+    psFits *fits = psFitsOpen(fileName, "r");
+    if (fits == NULL) {
         psError(PS_ERR_IO, false, "failed to open %s for output", fileName);
-        return NULL;
+        return false;
+    }
+    if (!psFitsMoveExtNum(fits, 1, true)) {
+        psError(PS_ERR_IO, false, "failed to move to first extension from %s", fileName);
+        return false;
     }
 
-    psArray *array = psFitsReadTable(fitsFile);
+    if (pHeader) {
+        *pHeader = psFitsReadHeader(NULL, fits);
+        if (!*pHeader) {
+            psError(PS_ERR_IO, false, "failed to header from %s", fileName);
+            return false;
+        }
+    }
 
-    psFitsClose(fitsFile);
+    if (pTable) {
+        *pTable = psFitsReadTable(fits);
+        if (*pTable == NULL) {
+            psError(PS_ERR_IO, false, "psFitsReadTable failed for %s", fileName);
+            return false;
+        }
+    }
 
-    if (array == NULL) {
-        psError(PS_ERR_IO, false, "psFitsReadTable failed for %s", fileName);
-        return NULL;
-    } 
+    psFitsClose(fits);
 
-    return array;
+    return true;
 }
 
@@ -32,9 +45,28 @@
 usage(char *program_name)
 {
-    fprintf(stderr, "usage: %s filename\n", program_name);
+    fprintf(stderr, "usage: %s [-header] [-simple] filename\n", program_name);
     exit(1);
 }
+
 int main(int argc, char *argv[])
 {
+    bool dumpHeader = false;
+    bool simple = false;
+    bool dumpTable = true;
+    int argnum;
+    if ((argnum = psArgumentGet(argc, argv, "-header"))) {
+        dumpHeader = true;
+        psArgumentRemove(argnum, &argc, argv);
+    }
+    if ((argnum = psArgumentGet(argc, argv, "-simple"))) {
+        simple = true;
+        psArgumentRemove(argnum, &argc, argv);
+    }
+    if ((argnum = psArgumentGet(argc, argv, "-headeronly"))) {
+        dumpTable = false;
+        dumpHeader = true;
+        psArgumentRemove(argnum, &argc, argv);
+    }
+
     if (argc != 2) {
         usage(argv[0]);
@@ -43,29 +75,85 @@
     psString fileName = argv[1];
 
-    psArray *array = readRequestTable(fileName);
-    if (array == NULL) {
-        psErrorStackPrint(stderr, "failed to read fits table: %s\n", fileName);
+    psMetadata *header;
+    psArray *array;
+    if (!readFitsFile(fileName, dumpHeader ? &header : NULL, dumpTable ? &array : NULL)) {
+        psErrorStackPrint(stderr, "failed to process fits table from: %s\n", fileName);
+        return 1;
+    }
+    if (dumpHeader) {
+        psString extname = psMetadataLookupStr(NULL, header, "EXTNAME");
+        if (!extname) {
+            psErrorStackPrint(stderr, "failed to find EXTNAME in fits header of: %s\n", fileName);
+            return 1;
+        }
+        psString req_name = psMetadataLookupStr(NULL, header, "REQ_NAME");
+        if (!req_name) {
+            psErrorStackPrint(stderr, "failed to find REQ_NAME in fits header of: %s\n", fileName);
+            return 1;
+        }
+        if (!strcmp(extname, "PS1_PS_REQUEST")) {
+            psString extver = psMetadataLookupStr(NULL, header, "EXTVER");
+            if (!extver) {
+                psErrorStackPrint(stderr, "failed to find EXTVER in fits header of: %s\n", fileName);
+                return 1;
+            }
+            printf("%s %s %s\n", extname, extver, req_name);
+        } else if (!strcmp(extname, "PS1_PS_RESULTS")) {
+            psS64 req_id = psMetadataLookupS64(NULL, header, "REQ_ID");
+            printf("%s %s %" PRId64 "\n", extname, req_name, req_id);
+        } else {
+            psErrorStackPrint(stderr, "do not recognize extname: %s in %s\n", extname, fileName);
+            return 1;
+        }
+    }
+    if (!dumpTable) {
+        // done
+        return 0;
+    }
+
+    if (!psArrayLength(array)) {
+        fprintf(stderr, "%s contains an empty table\n", fileName);
         return 1;
     }
 
-    if (!psArrayLength(array)) {
-        fprintf(stderr, "%s is an empty table\n", fileName);
-        exit(1);
-    }
-
-//    printf("FITS_TABLE METADATA\n");
     for (int i=0; i<psArrayLength(array); i++) {
-        printf("ROW_%d METADATA\n", i);
-        // psMetadataPrint(stderr, array->data[i], 0);
-        // psMetadataConfigWrite(array->data[i], "-");
         psString str = psMetadataConfigFormat(array->data[i]);
         if (!str) {
-            psErrorStackPrint(stderr, "Can't write to STDOUT\n");
-            exit(PS_EXIT_SYS_ERROR);
+            psErrorStackPrint(stderr, "failed to format metadata item\n");
+            return (PS_EXIT_SYS_ERROR);
         }
-        printf("%s", str);
-        printf("END\n");
+        if (!simple) {
+            printf("ROW_%d METADATA\n", i);
+            printf("%s", str);
+            printf("END\n");
+        } else {
+            // simple output format space separated values one line per row
+            char *p = str;
+            char *pnl;
+            while ((pnl = strchr(p, '\n'))) {
+                // terminate the string for this line
+                *pnl = 0;
+                bool blank = (p == pnl);
+                if (blank) {
+                    p = pnl + 1;
+                    continue;
+                }
+                // split line into space separated tokens
+                char *name = strtok(p, " ");
+                char *type = strtok(NULL, " ");
+                char *val = strtok(NULL, " ");
+
+                // avoid unused variables warning/error
+                (void) name; (void) type;
+
+                if (val) {
+                    printf("%s ", val);
+                }
+                // next line
+                p = pnl + 1;
+            }
+            printf("\n");
+        }
     }
-//   printf("END\n");
 
     return 0;
Index: /branches/czw_branch/cleanup/tools/diff_outputs.pl
===================================================================
--- /branches/czw_branch/cleanup/tools/diff_outputs.pl	(revision 25157)
+++ /branches/czw_branch/cleanup/tools/diff_outputs.pl	(revision 25158)
@@ -16,9 +16,9 @@
                                           'SOURCES', 'JPEG1', 'JPEG2',
                                           'KERNEL' ],
-                           'ALL' => [ 'IMAGE', 'MASK', 'VARIANCE',
-                                      'SOURCES', 'JPEG1', 'JPEG2',
-                                      'KERNEL', 'INVERSE.IMAGE',
-                                      'INVERSE.MASK', 'INVERSE.VARIANCE',
-                                      'INVERSE.SOURCES' ],
+                           'ALL' => [ 'IMAGE', 'MASK', 'VARIANCE', 'SOURCES', 'JPEG1', 'JPEG2', 'KERNEL',
+                                      'INVERSE.IMAGE', 'INVERSE.MASK', 'INVERSE.VARIANCE', 'INVERSE.SOURCES',
+                                      'INCONV.IMAGE', 'INCONV.MASK', 'INCONV.VARIANCE',
+                                      'REFCONV.IMAGE', 'REFCONV.MASK', 'REFCONV.VARIANCE',
+                               ],
                            'INVERSE' => [ 'INVERSE.IMAGE', 'INVERSE.MASK',
                                           'INVERSE.VARIANCE',
@@ -38,4 +38,10 @@
                              'INVERSE.VARIANCE' => '.inv.wt.fits', # Variance
                              'INVERSE.SOURCES' => '.inv.cmf', # Sources
+                             'INCONV.IMAGE' => '.inConv.fits', # Convolved input image
+                             'INCONV.MASK' => '.inConv.mk.fits', # Convolved input mask
+                             'INCONV.VARIANCE' => '.inConv.wt.fits', # Convolved input variance
+                             'REFCONV.IMAGE' => '.refConv.fits', # Convolved reference image
+                             'REFCONV.MASK' => '.refConv.mk.fits', # Convolved reference mask
+                             'REFCONV.VARIANCE' => '.refConv.wt.fits', # Convolved reference variance
                          };
 
