Index: /branches/czw_branch/cleanup/Ohana/src/getstar/include/dvoImagesAtCoords.h
===================================================================
--- /branches/czw_branch/cleanup/Ohana/src/getstar/include/dvoImagesAtCoords.h	(revision 25211)
+++ /branches/czw_branch/cleanup/Ohana/src/getstar/include/dvoImagesAtCoords.h	(revision 25212)
@@ -18,4 +18,13 @@
 Coords *MOSAIC;         // carries the mosaic into ReadImageHeader
 
+typedef struct {
+    int     id;
+    double  ra;
+    double  dec;
+    int     Nmatches;
+    int     *matches;
+    int     arrayLength;
+} Point;
+
 int WITH_PHU;
 int SOLO_PHU;
@@ -33,7 +42,5 @@
 Image *ReadImageFiles (char *filename, int *Nimages);
 int ReadImageHeader (Header *header, Image *image);
-int *MatchCoords(Image *, int, double, double, int *);
+int MatchCoords(Image *, int, Point *, int);
 
 int GetFileMode (Header *header);
-// int edge_check (double *x1, double *y1, double *x2, double *y2);
-// double opening_angle (double x1, double y1, double x2, double y2, double x3, double y3);
Index: /branches/czw_branch/cleanup/Ohana/src/getstar/src/MatchCoords.c
===================================================================
--- /branches/czw_branch/cleanup/Ohana/src/getstar/src/MatchCoords.c	(revision 25211)
+++ /branches/czw_branch/cleanup/Ohana/src/getstar/src/MatchCoords.c	(revision 25212)
@@ -5,8 +5,8 @@
 
 /* given coordinate, find images in list that contain the point */
-int *MatchCoords (Image *dbImages, int NdbImages, double ra, double dec, int *Nmatch) {
+int MatchCoords (Image *dbImages, int NdbImages, Point *points, int Npoints) {
   
-  int i, j, N, addtolist, status;
-  int NMATCH, nmatch, *match;
+  int i, j, N;
+  int totalMatches = 0;
   Coords tcoords;
   double r, d;
@@ -15,10 +15,4 @@
   double xmin, xmax, ymin, ymax;
 
-  *Nmatch = 0;
-
-  /* match represents the subset of overlapping images */
-  nmatch = 0;
-  NMATCH = 20;
-  ALLOCATE (match, int, NMATCH);
 
   /* setup links for mosaic WRP and DIS entries */
@@ -49,28 +43,32 @@
     }
 
-    // transform input point to image coords
-    double x, y;
-    int status = RD_to_XY(&x, &y, ra, dec, &dbImages[i].coords);
+    for (j = 0; j < Npoints; j++) {
+        Point *pt = points + j;
 
-    if (!status) {
-        // avoid matching antipodal skycells
-        continue;
-    }
+        // transform input point to image coords
+        double x, y;
+        int status = RD_to_XY(&x, &y, pt->ra, pt->dec, &dbImages[i].coords);
 
-    if ((x >= xmin && x <= xmax) && (y >= ymin && y <= ymax)) {
+        if (!status) {
+            // avoid matching antipodal skycells
+            continue;
+        }
 
-        match[nmatch] = i;
-        nmatch ++;
-        if (nmatch == NMATCH) {
-          NMATCH += 20;
-          REALLOCATE (match, int, NMATCH);
+        if ((x >= xmin && x <= xmax) && (y >= ymin && y <= ymax)) {
+            totalMatches++;
+
+            pt->matches[pt->Nmatches] = i;
+            pt->Nmatches ++;
+
+            if (pt->Nmatches == pt->arrayLength) {
+                pt->arrayLength += 20;
+                REALLOCATE (pt->matches, int, pt->arrayLength);
+            }
         }
     }
-      
-  }
-  if (VERBOSE) fprintf (stderr, "found %d overlapping images\n", nmatch);
+ }
+ if (VERBOSE) fprintf (stderr, "found %d overlapping images\n", totalMatches);
   
-  *Nmatch = nmatch;
-  return (match);
+ return (totalMatches);
 }
   
Index: /branches/czw_branch/cleanup/Ohana/src/getstar/src/dvoImagesAtCoords.c
===================================================================
--- /branches/czw_branch/cleanup/Ohana/src/getstar/src/dvoImagesAtCoords.c	(revision 25211)
+++ /branches/czw_branch/cleanup/Ohana/src/getstar/src/dvoImagesAtCoords.c	(revision 25212)
@@ -1,12 +1,6 @@
 # include "dvoImagesAtCoords.h"
 
-typedef struct {
-    int     id;
-    double  ra;
-    double  dec;
-} Point;
-
 static int readPoints(char *filename, Point **pointsOut);
-static int ListImagesAtCoords (Image *dbImages, int id, double ra, double dec, int *matches, int Nmatches);
+static int ListImagesAtCoords (Image *dbImages, Point *points, int Npoints);
 
 int main (int argc, char **argv) {
@@ -30,5 +24,5 @@
   if (astromFile) {
       dbImages = ReadImageFiles(astromFile, &NdbImages);
-    } else {
+  } else {
     /*** update the image table ***/
     /* setup image table format and lock */
@@ -53,10 +47,8 @@
   }
   
-  Point *pt;
-  for (i = 0, pt = points; i < Npoints; i++, pt++) {
-    matches = MatchCoords (dbImages, NdbImages, pt->ra, pt->dec, &Nmatches);
-    ListImagesAtCoords(dbImages, pt->id, pt->ra, pt->dec, matches, Nmatches);
+  if (MatchCoords (dbImages, NdbImages, points, Npoints)) {
+    ListImagesAtCoords(dbImages, points, Npoints);
   }
-
+  // XXX: should we exit with nonzero status if no matches were found?
   exit (0);
 }
@@ -83,6 +75,9 @@
 
     while ((Nread = fscanf(f, "%d %lf %lf\n", &pts[Npoints].id, &pts[Npoints].ra, &pts[Npoints].dec)) == 3) {
-        Npoints++;
-        if (Npoints >= LEN) {
+        pts[Npoints].Nmatches = 0;
+        ALLOCATE(pts[Npoints].matches, int, 20);
+        pts[Npoints].arrayLength = 20;
+
+        if (++Npoints >= LEN) {
             LEN += 20;
             REALLOCATE(pts, Point, LEN);
@@ -99,24 +94,33 @@
 }
 
-static int ListImagesAtCoords (Image *dbImages, int id, double ra, double dec, int *matches, int Nmatches)
+static int ListImagesAtCoords (Image *dbImages, Point *points, int Npoints) 
 {
+  int j;
   int i;
-  for (i = 0; i < Nmatches; i++) {
-    int N = matches[i];
+  for (j = 0; j < Npoints; j++) {
+      Point *pt = points + j;
+      for (i = 0; i < pt->Nmatches; i++) {
+        int N = pt->matches[i];
 
-    char *name;
-    // output of lookup is filename[class_id.hdr] for astrometry files
-    char *left_bracket = rindex(dbImages[N].name, '[');
-    if (left_bracket) {
-        name = strdup(left_bracket + 1);
-        // zap the .hdr]
-        char *dot = index(name, '.');
-        if (dot) {
-            *dot = 0;
+        char *name;
+        char *copy = NULL;
+        // output of lookup is filename[class_id.hdr] for astrometry files
+        char *left_bracket = rindex(dbImages[N].name, '[');
+        if (left_bracket) {
+            copy = strdup(left_bracket + 1);
+            name = copy;
+            // zap the .hdr]
+            char *dot = index(name, '.');
+            if (dot) {
+                *dot = 0;
+            }
+        } else {
+            name = dbImages[N].name;
         }
-    } else {
-        name = dbImages[N].name;
+        fprintf (stdout, "%d %lf %lf %s\n", pt->id, pt->ra, pt->dec, name);
+        if  (copy) {
+            free(copy);
+        }
     }
-    fprintf (stdout, "%d %lf %lf %s\n", id, ra, dec, name);
   }
   
Index: /branches/czw_branch/cleanup/ippScripts/scripts/ipp_image_path.pl
===================================================================
--- /branches/czw_branch/cleanup/ippScripts/scripts/ipp_image_path.pl	(revision 25211)
+++ /branches/czw_branch/cleanup/ippScripts/scripts/ipp_image_path.pl	(revision 25212)
@@ -108,7 +108,7 @@
             # remove the leading "file://" if present
             $path =~ s/^file\:\/\///;
+            $nfiles++;
+            print "$path\n";
         }
-        $nfiles++;
-        print "$path\n";
     }
     if (!$nfiles) {
Index: /branches/czw_branch/cleanup/ippTools/share/Makefile.am
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/Makefile.am	(revision 25211)
+++ /branches/czw_branch/cleanup/ippTools/share/Makefile.am	(revision 25212)
@@ -184,4 +184,7 @@
      pstamptool_pendingreq.sql \
      pstamptool_project.sql \
+     pstamptool_revertjob.sql \
+     pstamptool_revertreq.sql \
+     pstamptool_revertreq_deletejobs.sql \
      pxadmin_create_tables.sql \
      pxadmin_create_mirror_tables.sql \
Index: /branches/czw_branch/cleanup/ippTools/share/pstamptool_pendingjob.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/pstamptool_pendingjob.sql	(revision 25211)
+++ /branches/czw_branch/cleanup/ippTools/share/pstamptool_pendingjob.sql	(revision 25212)
@@ -1,4 +1,7 @@
-SELECT *
- FROM pstampJob
- WHERE state = 'run'
-    AND fault = 0
+SELECT pstampJob.*
+FROM pstampJob
+    JOIN pstampRequest using(req_id)
+WHERE pstampRequest.state = 'run'
+    AND pstampRequest.fault = 0
+    AND pstampJob.state = 'run'
+    AND pstampJob.fault = 0
Index: /branches/czw_branch/cleanup/ippTools/share/pstamptool_pendingreq.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/pstamptool_pendingreq.sql	(revision 25211)
+++ /branches/czw_branch/cleanup/ippTools/share/pstamptool_pendingreq.sql	(revision 25212)
@@ -7,2 +7,3 @@
     USING(ds_id)
  WHERE pstampRequest.state = 'new'
+    AND pstampRequest.fault = 0
Index: /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertjob.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertjob.sql	(revision 25212)
+++ /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertjob.sql	(revision 25212)
@@ -0,0 +1,5 @@
+UPDATE pstampJob 
+    JOIN pstampRequest USING(req_id)
+SET pstampJob.fault = 0
+WHERE  pstampRequest.state = 'run'
+    AND pstampJob.state = 'run'
Index: /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertreq.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertreq.sql	(revision 25212)
+++ /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertreq.sql	(revision 25212)
@@ -0,0 +1,4 @@
+UPDATE pstampRequest
+    SET fault = 0
+WHERE pstampRequest.state != 'stop'
+    
Index: /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertreq_deletejobs.sql
===================================================================
--- /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertreq_deletejobs.sql	(revision 25212)
+++ /branches/czw_branch/cleanup/ippTools/share/pstamptool_revertreq_deletejobs.sql	(revision 25212)
@@ -0,0 +1,5 @@
+-- delete jobs that got added by an incomplete pstamp parser run
+DELETE pstampJob
+FROM pstampJob
+    JOIN pstampRequest USING(req_id)
+WHERE pstampRequest.state = 'new'
Index: /branches/czw_branch/cleanup/ippTools/src/pstamptool.c
===================================================================
--- /branches/czw_branch/cleanup/ippTools/src/pstamptool.c	(revision 25211)
+++ /branches/czw_branch/cleanup/ippTools/src/pstamptool.c	(revision 25212)
@@ -44,4 +44,5 @@
 static bool pendingjobMode(pxConfig *config);
 static bool updatejobMode(pxConfig *config);
+static bool revertjobMode(pxConfig *config);
 static bool addprojectMode(pxConfig *config);
 static bool projectMode(pxConfig *config);
@@ -80,4 +81,5 @@
         MODECASE(PSTAMPTOOL_MODE_PENDINGJOB, pendingjobMode);
         MODECASE(PSTAMPTOOL_MODE_UPDATEJOB, updatejobMode);
+        MODECASE(PSTAMPTOOL_MODE_REVERTJOB, revertjobMode);
         MODECASE(PSTAMPTOOL_MODE_ADDPROJECT, addprojectMode);
         MODECASE(PSTAMPTOOL_MODE_MODPROJECT, modprojectMode);
@@ -485,17 +487,40 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    PXOPT_LOOKUP_S64(req_id,     config->args, "-req_id",     true, false);
-
-    // printf("Revert request %" PRId64 "\n", req_id);
+    psMetadata *where = psMetadataAlloc();
+
+    PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-fault", "req_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-state", "pstampRequest.state", "==");
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
+        return false;
+    }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psFree(where);
+
+    // delete any jobs that were queued by requests that didn't complete parsing (pstampRequest.state = 'new'
+    // If state =  'run' was supplied this will be a no-op
+    psString query = pxDataGet("pstamptool_revertreq_deletejobs.sql");
+    psStringAppend(&query, " AND %s", whereClause);
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    psFree(query);
+
+    // clear fault for requests
+    query = pxDataGet("pstamptool_revertreq.sql");
+    psStringAppend(&query, " AND %s", whereClause);
     
-    if (!p_psDBRunQueryF(config->dbh, "DELETE FROM pstampJob where req_id = %" PRId64, req_id)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
-    if (!p_psDBRunQueryF(config->dbh, 
-        "UPDATE pstampRequest set state ='new', name=NULL, reqType=NULL, fault=0 where req_id = %" PRId64, req_id)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
+    psFree(whereClause);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    psFree(query);
 
     return true;
@@ -728,4 +753,34 @@
     return true;
 }
+
+static bool revertjobMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+
+    PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-fault",  "fault", "==");
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
+        return false;
+    }
+
+    psString query = pxDataGet("pstamptool_revertjob.sql");
+    psString whereClause = psDBGenerateWhereConditionSQL(where, "pstampJob");
+    psStringAppend(&query, " AND %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+    
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    return true;
+}
 static bool addprojectMode(pxConfig *config)
 {
Index: /branches/czw_branch/cleanup/ippTools/src/pstamptool.h
===================================================================
--- /branches/czw_branch/cleanup/ippTools/src/pstamptool.h	(revision 25211)
+++ /branches/czw_branch/cleanup/ippTools/src/pstamptool.h	(revision 25212)
@@ -39,4 +39,5 @@
     PSTAMPTOOL_MODE_JOBRESULT,
     PSTAMPTOOL_MODE_UPDATEJOB,
+    PSTAMPTOOL_MODE_REVERTJOB,
     PSTAMPTOOL_MODE_ADDPROJECT,
     PSTAMPTOOL_MODE_MODPROJECT,
Index: /branches/czw_branch/cleanup/ippTools/src/pstamptoolConfig.c
===================================================================
--- /branches/czw_branch/cleanup/ippTools/src/pstamptoolConfig.c	(revision 25211)
+++ /branches/czw_branch/cleanup/ippTools/src/pstamptoolConfig.c	(revision 25212)
@@ -97,5 +97,7 @@
     // -revertreq
     psMetadata *revertreqArgs = psMetadataAlloc();
-    psMetadataAddS64(revertreqArgs, PS_LIST_TAIL, "-req_id", 0,            "req_id for which to revert", 0); 
+    psMetadataAddS64(revertreqArgs, PS_LIST_TAIL, "-req_id", 0,     "req_id to revert", 0); 
+    psMetadataAddS16(revertreqArgs, PS_LIST_TAIL, "-fault",  0,     "fault to revert", 0); 
+    psMetadataAddStr(revertreqArgs, PS_LIST_TAIL, "-state", 0,      "state to revert", NULL); 
 
     // -addjob
@@ -129,4 +131,10 @@
     psMetadataAddStr(updatejobArgs, PS_LIST_TAIL, "-fault", 0,            "new result", NULL); 
 
+    // -revertjob
+    psMetadata *revertjobArgs = psMetadataAlloc();
+    psMetadataAddS64(revertjobArgs, PS_LIST_TAIL, "-req_id", 0,     "req_id to revert", 0); 
+    psMetadataAddS64(revertjobArgs, PS_LIST_TAIL, "-job_id", 0,     "job_id to revert", 0); 
+    psMetadataAddS16(revertjobArgs, PS_LIST_TAIL, "-fault",  0,     "fault to revert", 0); 
+
     // -addproject
     psMetadata *addprojectArgs = psMetadataAlloc();
@@ -159,5 +167,5 @@
     PXOPT_ADD_MODE("-addreq",          "", PSTAMPTOOL_MODE_ADDREQ,       addreqArgs);
     PXOPT_ADD_MODE("-pendingreq",      "", PSTAMPTOOL_MODE_PENDINGREQ,   pendingreqArgs);
-    PXOPT_ADD_MODE("-updatereq",    "", PSTAMPTOOL_MODE_UPDATEREQ, updatereqArgs);
+    PXOPT_ADD_MODE("-updatereq",       "", PSTAMPTOOL_MODE_UPDATEREQ, updatereqArgs);
     PXOPT_ADD_MODE("-listreq",         "", PSTAMPTOOL_MODE_LISTREQ,      listreqArgs);
     PXOPT_ADD_MODE("-completedreq",    "", PSTAMPTOOL_MODE_COMPLETEDREQ, completedreqArgs);
@@ -167,5 +175,6 @@
     PXOPT_ADD_MODE("-listjob",         "", PSTAMPTOOL_MODE_LISTJOB,      listjobArgs);
     PXOPT_ADD_MODE("-pendingjob",      "", PSTAMPTOOL_MODE_PENDINGJOB,   pendingjobArgs);
-    PXOPT_ADD_MODE("-updatejob",    "", PSTAMPTOOL_MODE_UPDATEJOB, updatejobArgs);
+    PXOPT_ADD_MODE("-updatejob",       "", PSTAMPTOOL_MODE_UPDATEJOB,    updatejobArgs);
+    PXOPT_ADD_MODE("-revertjob",       "", PSTAMPTOOL_MODE_REVERTJOB,    revertjobArgs);
 
     PXOPT_ADD_MODE("-adddatastore",    "", PSTAMPTOOL_MODE_ADDDATASTORE, adddatastoreArgs);
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksio.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksio.c	(revision 25211)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksio.c	(revision 25212)
@@ -654,4 +654,15 @@
             streaksExit("", PS_EXIT_DATA_ERROR);
         }
+
+        // Ensure input is of the expected type
+        psDataType expected = isMask ? PS_TYPE_IMAGE_MASK : PS_TYPE_F32; // Expected type for image
+        for (int i = 0; i < in->imagecube->n; i++) {
+            psImage *image = in->imagecube->data[i]; // Image of interest
+            if (image->type.type != expected) {
+                psImage *temp = psImageCopy(NULL, image, expected);
+                psFree(image);
+                in->imagecube->data[i] = temp;
+            }
+        }
     }
     setDataExtent(stage, in, (stage == IPP_STAGE_RAW) && !isMask);
@@ -670,4 +681,5 @@
     sfile->fits->options = psFitsOptionsAlloc();
     sfile->fits->options->scaling = PS_FITS_SCALE_MANUAL;
+    sfile->fits->options->fuzz = false;
     sfile->fits->options->bitpix = bitpix;
     sfile->fits->options->bscale = bscale;
@@ -1114,12 +1126,12 @@
                 // these gets are not necessary, we could just set the pixels to nan
                 // but I want to get the counts
-                double imageVal  = psImageGet(image, x, y);
+                double imageVal  = image->data.F32[y][x];
                 psU32 maskVal;
                 if (sfiles->stage == IPP_STAGE_RAW) {
                     unsigned int xChip, yChip;
                     cellToChipInt(&xChip, &yChip, sfiles->astrom, x, y);
-                    maskVal = psImageGet(mask, xChip, yChip);
+                    maskVal = mask->data.PS_TYPE_IMAGE_MASK_DATA[yChip][xChip];
                 } else {
-                    maskVal = psImageGet(mask, x, y);
+                    maskVal = mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x];
                 }
                 if (maskVal & maskMask) {
@@ -1127,11 +1139,11 @@
                     if (!isExciseValue(imageVal, sfiles->inImage->exciseValue)) {
                         ++nandPixels;
-                        psImageSet(image, x, y, exciseValue);
+                        image->data.F32[y][x] = exciseValue;
                     }
                     if (weight) {
-                        double weightVal = weight ? psImageGet(weight, x, y) : 0;
+                        double weightVal = weight ? weight->data.F32[y][x] : 0;
                         if (!isnan(weightVal)) {
                             ++nandWeights;
-                            psImageSet(weight, x, y, NAN);
+                            weight->data.F32[y][x] = NAN;
                         }
                     }
Index: /branches/czw_branch/cleanup/magic/remove/src/streaksremove.c
===================================================================
--- /branches/czw_branch/cleanup/magic/remove/src/streaksremove.c	(revision 25211)
+++ /branches/czw_branch/cleanup/magic/remove/src/streaksremove.c	(revision 25212)
@@ -12,10 +12,11 @@
 static pmConfig *parseArguments(int argc, char **argv);
 static bool readAndCopyToOutput(streakFiles *sf, bool exciseAll);
-static void exciseNonWarpedPixels(streakFiles *sfiles, double newMaskValue);
+static void exciseNonWarpedPixels(streakFiles *sfiles, psImageMaskType newMaskValue);
 static bool warpedPixel(streakFiles *sfiles, int x, int y);
-static void excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, double newMaskValue);
+static void excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, psImageMaskType newMaskValue);
 static void writeImages(streakFiles *sf, bool exciseImageCube);
 static void updateAstrometry(streakFiles *sfiles);
-static void censorSources(streakFiles *sfiles, psU32 maskStreak);
+static void censorSources(streakFiles *sfiles, psImageMaskType maskStreak);
+static long censorPixels(streakFiles *sfiles, psImage * pixels, bool checkNonWarpedPixels, psU16 maskStreak);
 
 int
@@ -146,22 +147,7 @@
                 }
 
-
                 psTimerStart("REMOVE_STREAKS");
 
-                for (int y=0 ; y < sfiles->inImage->numRows; y++) {
-                    for (int x = 0; x < sfiles->inImage->numCols; x++) {
-                        if (psImageGet(pixels, x, y)) {
-                            ++totalStreakPixels;
-                            if (!checkNonWarpedPixels || warpedPixel(sfiles, x, y)) {
-
-                                excisePixel(sfiles, x, y, true, maskStreak);
-
-                            } else {
-                                // This pixel was not included in any warp and has thus already excised
-                                // by exciseNonWarpedPixels
-                            }
-                        }
-                    }
-                }
+                totalStreakPixels += censorPixels(sfiles, pixels, checkNonWarpedPixels, maskStreak);
 
                 psLogMsg("streaksremove", PS_LOG_INFO, "time to remove streak pixels: %f\n", psTimerClear("REMOVE_STREAKS"));
@@ -254,4 +240,27 @@
 
     return 0;
+}
+
+static long
+censorPixels(streakFiles *sfiles, psImage *pixels, bool checkNonWarpedPixels, psU16 maskStreak)
+{
+    long streakPixels = 0;
+
+    for (int y=0 ; y < sfiles->inImage->numRows; y++) {
+        for (int x = 0; x < sfiles->inImage->numCols; x++) {
+            if (psImageGet(pixels, x, y)) {
+                ++streakPixels;
+                if (!checkNonWarpedPixels || warpedPixel(sfiles, x, y)) {
+
+                    excisePixel(sfiles, x, y, true, maskStreak);
+
+                } else {
+                    // This pixel was not included in any warp and has thus already excised
+                    // by exciseNonWarpedPixels
+                }
+            }
+        }
+    }
+    return streakPixels;
 }
 
@@ -665,5 +674,5 @@
 
 static void
-excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, double newMaskValue)
+excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, psImageMaskType newMaskValue)
 {
     double exciseValue = sfiles->inImage->exciseValue;
@@ -674,17 +683,17 @@
     }
 
-    double imageValue  = psImageGet (sfiles->inImage->image,  x, y);
+    float imageValue  = sfiles->inImage->image->data.F32[y][x];
     if (sfiles->recImage && !isExciseValue(imageValue, sfiles->inImage->exciseValue) ) {
-        psImageSet (sfiles->recImage->image,  x, y, imageValue);
+        sfiles->recImage->image->data.F32[y][x] = imageValue;
     }
 
     if (sfiles->transparentStreaks == 0) {
-        psImageSet (sfiles->outImage->image,  x, y, exciseValue);
+        sfiles->outImage->image->data.F32[y][x] = exciseValue;
     } else {
         if (streak) {
             // as a visualization aid don't mask the pixel, just change the intensity
-            psImageSet (sfiles->outImage->image,  x, y, imageValue + sfiles->transparentStreaks);
+            sfiles->outImage->image->data.F32[y][x] = imageValue + sfiles->transparentStreaks;
         } else {
-            psImageSet (sfiles->outImage->image,  x, y, exciseValue);
+            sfiles->outImage->image->data.F32[y][x] = exciseValue;
         }
     }
@@ -692,21 +701,21 @@
     if (sfiles->outWeight) {
         if (sfiles->recWeight) {
-            double weightValue = psImageGet (sfiles->inWeight->image, x, y);
-            psImageSet (sfiles->recWeight->image, x, y, weightValue);
+            sfiles->recWeight->image->data.F32[y][x] = sfiles->inWeight->image->data.F32[y][x];
         }
         // Assume that weight images are always a floating point type
-        psImageSet (sfiles->outWeight->image, x, y, NAN);
+        sfiles->outWeight->image->data.F32[y][x] = NAN;
     }
     if (sfiles->outMask) {
         if (sfiles->recMask) {
-            double maskValue   = psImageGet (sfiles->inMask->image,   x, y);
-            psImageSet (sfiles->recMask->image,   x, y, maskValue);
-        }
-        psImageSet (sfiles->outMask->image,   x, y, newMaskValue);
+            sfiles->recMask->image->data.PS_TYPE_IMAGE_MASK_DATA[y][x] =
+                sfiles->inMask->image->data.PS_TYPE_IMAGE_MASK_DATA[y][x];
+        }
+        sfiles->outMask->image->data.PS_TYPE_IMAGE_MASK_DATA[y][x] =
+            sfiles->inMask->image->data.PS_TYPE_IMAGE_MASK_DATA[y][x] | newMaskValue;
     }
 }
 
 static void
-exciseNonWarpedPixels(streakFiles *sfiles, double newMaskValue)
+exciseNonWarpedPixels(streakFiles *sfiles, psImageMaskType newMaskValue)
 {
     int cell_x0 = sfiles->astrom->cell_x0;
@@ -784,5 +793,5 @@
 // streak mask
 static void
-censorSources(streakFiles *sfiles, psU32 maskStreak)
+censorSources(streakFiles *sfiles, psImageMaskType maskStreak)
 {
     if ((!sfiles->inSources) || (!sfiles->outMask)) {
@@ -855,5 +864,5 @@
             psF32 y = psMetadataLookupF32(NULL, row, "Y_PSF");
 
-            psU32 mask = psImageGet(maskImage, x, y);
+            psImageMaskType mask = maskImage->data.PS_TYPE_IMAGE_MASK_DATA[(int)y][(int)x];
 
             // Key the source if the center pixel is not masked with maskStreak
Index: /branches/czw_branch/cleanup/pstamp/scripts/pstamp_finish.pl
===================================================================
--- /branches/czw_branch/cleanup/pstamp/scripts/pstamp_finish.pl	(revision 25211)
+++ /branches/czw_branch/cleanup/pstamp/scripts/pstamp_finish.pl	(revision 25212)
@@ -254,5 +254,5 @@
         # register the fileset
         my $command = "$dsreg --list $reglist_name --add $fileset --product $product --type PSRESULTS";
-        $command .= " --link --datapath $out_dir";
+        $command .= " --link --datapath $out_dir --ps0 $req_id";
         $command .= " --dbname $dbname" if $dbname;
 
Index: /branches/czw_branch/cleanup/pstamp/scripts/pstamp_parser_run.pl
===================================================================
--- /branches/czw_branch/cleanup/pstamp/scripts/pstamp_parser_run.pl	(revision 25211)
+++ /branches/czw_branch/cleanup/pstamp/scripts/pstamp_parser_run.pl	(revision 25212)
@@ -14,4 +14,12 @@
 use File::Basename qw( basename dirname);
 use POSIX qw( strftime );
+use Carp;
+use IPC::Cmd 0.36 qw( can_run run );
+
+use PS::IPP::Metadata::Config;
+use PS::IPP::Metadata::Stats;
+use PS::IPP::Metadata::List qw( parse_md_list );
+
+use PS::IPP::Config qw( :standard );
 
 my $req_id;
@@ -39,26 +47,8 @@
 }
 
-die "--req_id --uri --product are required" 
+my_die("--req_id --uri --product are required", $req_id, $PS_EXIT_CONFIG_ERROR)
     if !defined($req_id) or
        !defined($uri) or
        !defined($product);
-
-use IPC::Cmd 0.36 qw( can_run run );
-
-use PS::IPP::Metadata::Config;
-use PS::IPP::Metadata::Stats;
-use PS::IPP::Metadata::List qw( parse_md_list );
-
-use PS::IPP::Config qw($PS_EXIT_SUCCESS
-		       $PS_EXIT_UNKNOWN_ERROR
-		       $PS_EXIT_SYS_ERROR
-		       $PS_EXIT_CONFIG_ERROR
-		       $PS_EXIT_PROG_ERROR
-		       $PS_EXIT_DATA_ERROR
-		       $PS_EXIT_TIMEOUT_ERROR
-		       metadataLookupStr
-		       metadataLookupBool
-		       caturi
-		       );
 
 my $ipprc = PS::IPP::Config->new(); # IPP Configuration
@@ -80,10 +70,12 @@
 my $datedir = "$pstamp_workdir/$datestr";
 if (! -e $datedir ) {
-    mkdir $datedir or die "failed to create working directory $datedir for request id $req_id";
+    mkdir $datedir or my_die( "failed to create working directory $datedir for request id $req_id", $req_id,
+        $PS_EXIT_CONFIG_ERROR);
 }
 
 my $workdir = "$datedir/$req_id";
 if (! -e $workdir ) {
-    mkdir $workdir or die "failed to create working directory $workdir for request id $req_id";
+    mkdir $workdir or my_die("failed to create working directory $workdir for request id $req_id", $req_id,
+        $PS_EXIT_CONFIG_ERROR);
 }
 
@@ -119,18 +111,18 @@
         run(command => $command, verbose => $verbose);
     unless ($success) {
-        die("Unable to perform $command error code: $error_code");
+        my_die("Unable to perform $command error code: $error_code", $req_id, $error_code >> 8);
     }
 } elsif ($uri ne $new_uri) {
     # put a link to the file into the workdir
     if (-e $new_uri) {
-        unlink $new_uri or die "failed to unlink $new_uri";
+        unlink $new_uri or my_die("failed to unlink $new_uri", $req_id, $PS_EXIT_UNKNOWN_ERROR);
     }
     if (! symlink $uri, $new_uri) {
-        die ("failed to link request file $uri to workdir $workdir");
+        my_die ("failed to link request file $uri to workdir $workdir", $req_id, $PS_EXIT_UNKNOWN_ERROR);
     }
 }
 $uri = $new_uri;
 
-die "request file $uri not found" if ! -e $uri;
+my_die("request file $uri not found", $req_id, $PS_EXIT_UNKNOWN_ERROR) if ! -e $uri;
 
 #  if product was not defined (in database), use the default
@@ -263,2 +255,20 @@
     }
 }
+
+sub my_die {
+    my $msg = shift;
+    my $req_id = shift;
+    my $fault = shift;
+
+    carp($msg);
+
+    my $command = "$pstamptool -updatereq -req_id $req_id  -fault $fault";
+    $command   .= " -dbname $dbname" if $dbname;
+    $command   .= " -dbserver $dbserver" if $dbserver;
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+        run(command => $command, verbose => $verbose);
+    unless ($success) {
+        die("Unable to perform $command error code: $error_code");
+    }
+    exit $fault;
+}
Index: /branches/czw_branch/cleanup/pstamp/scripts/pstampparse.pl
===================================================================
--- /branches/czw_branch/cleanup/pstamp/scripts/pstampparse.pl	(revision 25211)
+++ /branches/czw_branch/cleanup/pstamp/scripts/pstampparse.pl	(revision 25212)
@@ -14,4 +14,5 @@
 use PS::IPP::PStamp::Job qw( :standard );
 use File::Temp qw(tempfile);
+use Carp;
 
 my $verbose;
@@ -96,10 +97,12 @@
 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 => $verbose);
+        run(command => $command, verbose => 0);
     my $exitStatus = $error_code >> 8;
     if ($success) {
@@ -183,4 +186,6 @@
 
     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);
@@ -214,4 +219,9 @@
     $need_magic = $proj_hash->{need_magic};
 
+    # Temporary hack so that MOPS can get at non-magicked data
+    if ($product eq "mops-pstamp-results") {
+        $need_magic = 0;
+    }
+
     # collect rows with the same images of interest in a list so that they
     # can be looked up together
@@ -247,9 +257,11 @@
         next;
     } else {
-        # Call PS::IPP::PStamp::Job's locate_images subroutine to get the parameters for this
+        # Call PS::IPP::PStamp::Job locate_images subroutine to get the images for this
         # request specification. An array reference is returned.
         my ($x, $y);
+
         $imageList = locate_images($ipprc, $image_db, $req_type, $stage, $id, $search_component,
-                $skycenter, $x, $y, $mjd_min, $mjd_max, $filter, $verbose);
+                $inverse, $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;
@@ -283,13 +295,7 @@
     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;
@@ -332,9 +338,10 @@
         if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
             # XXX: should we add a faulted job so the client can know what happened if no images come back?
-            print STDERR "skippping non-magicked image $imagefile\n" if $verbose;
+            print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
 
             # for now assume yes.
 
             insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
+            $num_jobs++;
 
             next;
@@ -372,14 +379,15 @@
         my $fault = 0;
 
-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;
-        }
-}
+        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;
+            }
+        }
 
         $num_jobs++;
@@ -410,4 +418,9 @@
         }
     }
+    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;
 }
@@ -480,5 +493,5 @@
             if ($npoints) {
                 # we collected a set of sky coordintates above filter the images so that only
-                # those tat contain the centers are processed
+                # those that contain the centers are processed
                 my $command = "$dvoImagesAtCoords $pointsListName";
                 if ($have_skycells) {
@@ -511,5 +524,5 @@
                     my ($rownum, undef, undef, $component) = split " ", $line;
 
-                    # I guess since we need this function we should be useing a hash for rowList 
+                    # I guess since we need this function we should be using a hash for rowList 
                     my $row = findRow($rownum, $rowList);
                     $row->{components}->{$component} = 1;
@@ -616,4 +629,5 @@
     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/ppstamp.c
===================================================================
--- /branches/czw_branch/cleanup/pstamp/src/ppstamp.c	(revision 25211)
+++ /branches/czw_branch/cleanup/pstamp/src/ppstamp.c	(revision 25212)
@@ -29,9 +29,5 @@
 
     // find the pixels that we need to copy, setup the output image
-    if (ppstampMakeStamp(config, options)) {
-        exitCode = 0;
-    } else {
-        exitCode = PS_EXIT_DATA_ERROR;
-    }
+    exitCode = ppstampMakeStamp(config, options);
 
     psLogMsg ("ppstamp", 3, "Complete ppstamp run: %f sec\n", psTimerMark(TIMERNAME));
Index: /branches/czw_branch/cleanup/pstamp/src/ppstamp.h
===================================================================
--- /branches/czw_branch/cleanup/pstamp/src/ppstamp.h	(revision 25211)
+++ /branches/czw_branch/cleanup/pstamp/src/ppstamp.h	(revision 25212)
@@ -20,5 +20,5 @@
 bool ppstampParseCamera(pmConfig *config);
 
-bool ppstampMakeStamp(pmConfig *config, ppstampOptions *);
+int ppstampMakeStamp(pmConfig *config, ppstampOptions *);
 pmFPAfile * ppstampBuildMosaic(pmConfig *config, pmFPAfile *input, pmFPAview *view);
 
Index: /branches/czw_branch/cleanup/pstamp/src/ppstampMakeStamp.c
===================================================================
--- /branches/czw_branch/cleanup/pstamp/src/ppstampMakeStamp.c	(revision 25211)
+++ /branches/czw_branch/cleanup/pstamp/src/ppstampMakeStamp.c	(revision 25212)
@@ -174,6 +174,6 @@
 static psImage *extractStamp(psImage *image, psRegion region, double value)
 {
-    int width  = region.x1 - region.x0;
-    int height = region.y1 - region.y0;
+    int width  = region.x1 - region.x0 + 0.5;
+    int height = region.y1 - region.y0 + 0.5;
 
     if (width < 0) {
@@ -252,5 +252,5 @@
 // Build the postage stamp output file
 
-static bool makeStamp(pmConfig *config, ppstampOptions *options, pmFPAfile *input,
+static int makeStamp(pmConfig *config, ppstampOptions *options, pmFPAfile *input,
                 pmChip *inChip, pmFPAview *view)
 {
@@ -260,5 +260,5 @@
     if (!output) {
         psError(PS_ERR_UNKNOWN, false, "Can't find output data\n");
-        return false;
+        return PS_EXIT_DATA_ERROR;
     }
     char *fpaName = psMetadataLookupStr(NULL, input->fpa->concepts, "FPA.OBS"); // Name of FPA
@@ -284,5 +284,5 @@
         pmFPAfile *mosaic = ppstampBuildMosaic(config, input, view);
         if (mosaic == NULL) {
-            return false;
+            return PS_EXIT_UNKNOWN_ERROR;
         }
         srcFile = mosaic;
@@ -362,5 +362,5 @@
         status = copyMetadata(output, input, inChip, options);
     }
-    return status;
+    return status ? PS_EXIT_SUCCESS : PS_EXIT_UNKNOWN_ERROR;
 }
 
@@ -574,8 +574,8 @@
 }
 
-bool ppstampMakeStamp (pmConfig *config, ppstampOptions *options)
+int ppstampMakeStamp (pmConfig *config, ppstampOptions *options)
 {
     bool        status = false;
-    bool        returnval = false;;
+    int        returnval = PS_EXIT_SUCCESS;;
     bool        foundOverlap = false;
 
@@ -583,5 +583,5 @@
     if (!status) {
         psError(PS_ERR_UNKNOWN, true, "Can't find input file!\n");
-        return false;
+        return PS_EXIT_DATA_ERROR;
     }
 
@@ -591,5 +591,5 @@
     } else if (astrom->camera != input->camera) {
         psError(PS_ERR_UNKNOWN, true, "Input camera and astrometry camera do not match");
-        return false;
+        return PS_EXIT_CONFIG_ERROR;
     }
 
@@ -600,5 +600,5 @@
         psError(PS_ERR_UNKNOWN, false, "Failed to load input.");
         psFree (view);
-        return false;
+        return PS_EXIT_DATA_ERROR;
     }
     bool bilevelAstrometry  = false;
@@ -614,5 +614,5 @@
             psError(PS_ERR_UNKNOWN, false, "Unable to read bilevel mosaic astrometry for input FPA.");
             psFree(view);
-            return false;
+            return PS_EXIT_DATA_ERROR;
         }
     }
@@ -647,5 +647,5 @@
             break;
         case PSTAMP_ERROR:
-            returnval = false;
+            returnval = PS_EXIT_UNKNOWN_ERROR;
             allDone = true;
             break;
@@ -667,6 +667,7 @@
     psFree(view);
 
-    if (!foundOverlap) {
+    if (!foundOverlap && (returnval == PS_EXIT_SUCCESS)) {
         fprintf(stderr, "ROI not found in input\n");
+        returnval = PSTAMP_NO_OVERLAP;
     }
 
Index: /branches/czw_branch/cleanup/pstamp/src/pstamp.h
===================================================================
--- /branches/czw_branch/cleanup/pstamp/src/pstamp.h	(revision 25211)
+++ /branches/czw_branch/cleanup/pstamp/src/pstamp.h	(revision 25212)
@@ -42,5 +42,6 @@
 	PSTAMP_NOT_AVAILABLE    = 25,
 	PSTAMP_GONE             = 26,
-	PSTAMP_NO_JOBS_QUEUED   = 27
+	PSTAMP_NO_JOBS_QUEUED   = 27,
+        PSTAMP_NO_OVERLAP       = 28
 } pstampJobErrors;
 
