Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/burnparams.h
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/burnparams.h	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/burnparams.h	(revision 25210)
@@ -55,3 +55,5 @@
 EXTERN int EXPIRE_TRAIL_TIME;	/* Expire trails after this interval */
 
+EXTERN int PERSIST_RETAIN;	/* Retain bad-slope persistence fits */
+
 #endif /* _INCLUDED_burnparams_ */
Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/burntool.c
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/burntool.c	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/burntool.c	(revision 25210)
@@ -100,4 +100,6 @@
    EXPIRE_TRAIL_TIME = 2000;	/* Expire a persist after this [sec] */
 
+   PERSIST_RETAIN = 0;		/* Retain persists with bad slopes? */
+
 /* Parse the args */
    cellxy = -1;
@@ -174,4 +176,8 @@
       } else if(strncmp(argv[i], "infits=", 7) == 0) { /* infits=fname */
 	 persistfitsfile = argv[i] + 7;
+
+/* Keep persistence streaks which had a bad slope? */
+      } else if(strncmp(argv[i], "persist=", 8) == 0) {/* persist={t|f} */
+	 PERSIST_RETAIN = argv[i][8] == 'y' || argv[i][8] == '1' || argv[i][8] == 't';
 
 /* Output file for PSF gallery */
Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/man/burntool.1
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/man/burntool.1	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/man/burntool.1	(revision 25210)
@@ -53,4 +53,12 @@
 	power laws; downward burns as exponentials.
 	
+	The fit to downward, persistence burns may have an unreasonable "slope"
+	(meaning exponential sign), increasing away from the burn origin.
+	These are discarded unless "persist=t" is invoked.  It is possible
+	for the fit to be fooled by uncataloged stars, so the persistence
+	can be kept in the output file with "persist=t" (although no fit
+	correction is applied) and they will propagate from input to output
+	until they finally achieve a legal fit with negligible amplitude.
+
 	Burntool also identifies really blasted areas which are saturated from
 	top to bottom.  These cannot be fitted, but are carried along for
@@ -231,4 +239,8 @@
                 'in' takes precedence.
 
+	persist={t|f}
+		Retain persistence streaks whose fit slope turned out to be
+		unreasonable.
+
 	out=fname      
 		Output file for burn streaks
@@ -332,4 +344,5 @@
 BUGS:
 	090224: Still in development
+	090810: Squished a few memory bugs
 
 SEE ALSO:
Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/persist_fits.c
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/persist_fits.c	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/persist_fits.c	(revision 25210)
@@ -222,6 +222,14 @@
       for(k=0; k<cell[j].npersist; k++) 
       {
-         if(cell[j].persist[k].fiterr) continue;
-         if(cell[j].persist[k].nfit <= 0) continue;
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].persist[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].persist[k].fiterr) continue;
+	       if(cell[j].persist[k].nfit <= 0) continue;
+	    }
+	 } else {
+	    if(cell[j].persist[k].fiterr) continue;
+	    if(cell[j].persist[k].nfit <= 0) continue;
+	 }
          num_areas++;
          num_fits += cell[j].persist[k].nfit;
@@ -232,7 +240,16 @@
       {
 	 if(!cell[j].burn[k].burned) continue;
-	 if(cell[j].burn[k].fiterr && 
-	    cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
-	 if(cell[j].burn[k].nfit <= 0) continue;
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].burn[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].burn[k].fiterr && 
+		  cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	       if(cell[j].burn[k].nfit <= 0) continue;
+	    }
+	 } else {
+	    if(cell[j].burn[k].fiterr && 
+	       cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	    if(cell[j].burn[k].nfit <= 0) continue;
+	 }
          num_areas++;
          num_fits += cell[j].burn[k].nfit;
@@ -329,6 +346,14 @@
       for(k=0; k<cell[j].npersist; k++) 
       {
-         if(cell[j].persist[k].fiterr) continue;
-         if(cell[j].persist[k].nfit <= 0) continue;     
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].persist[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].persist[k].fiterr) continue;
+	       if(cell[j].persist[k].nfit <= 0) continue;     
+	    }
+	 } else {
+	    if(cell[j].persist[k].fiterr) continue;
+	    if(cell[j].persist[k].nfit <= 0) continue;     
+	 }
 
          result = write_area_row(hu, data, table, row++, &(cell[j].persist[k]));
@@ -340,7 +365,16 @@
       {
 	 if(!cell[j].burn[k].burned) continue;
-	 if(cell[j].burn[k].fiterr && 
-	    cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
-	 if(cell[j].burn[k].nfit <= 0) continue;
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].burn[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].burn[k].fiterr && 
+		  cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	       if(cell[j].burn[k].nfit <= 0) continue;
+	    }
+	 } else {
+	    if(cell[j].burn[k].fiterr && 
+	       cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	    if(cell[j].burn[k].nfit <= 0) continue;
+	 }
 
          result = write_area_row(hu, data, table, row++, &(cell[j].burn[k]));
@@ -426,5 +460,12 @@
       for(k=0; k<cell[j].npersist; k++) 
       {
-         if(cell[j].persist[k].fiterr) continue;
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].persist[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].persist[k].fiterr) continue;
+	    }
+	 } else {
+	    if(cell[j].persist[k].fiterr) continue;
+	 }
 	 for(i=0; i<cell[j].persist[k].nfit; i++) 
          {
@@ -441,6 +482,14 @@
       {
 	 if(!cell[j].burn[k].burned) continue;
-	 if(cell[j].burn[k].fiterr && 
-	    cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].burn[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].burn[k].fiterr && 
+		  cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	    }
+	 } else {
+	    if(cell[j].burn[k].fiterr && 
+	       cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	 }
 
 	 for(i=0; i<cell[j].burn[k].nfit; i++) 
Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/persistio.c
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/persistio.c	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/persistio.c	(revision 25210)
@@ -51,15 +51,16 @@
 	     &boxbuf[nbox].slope, &boxbuf[nbox].nfit,
 	     &boxbuf[nbox].sxfit, &boxbuf[nbox].exfit);
-      if(boxbuf[nbox].nfit <= 0) continue;
-      boxbuf[nbox].zero = (double *)calloc(boxbuf[nbox].nfit, sizeof(double));
-      boxbuf[nbox].xfit = (int *)calloc(boxbuf[nbox].nfit, sizeof(int));
-      boxbuf[nbox].yfit = (int *)calloc(boxbuf[nbox].nfit, sizeof(int));
-      for(i=0; i<boxbuf[nbox].nfit; i++) {
-	 if(fgets(line, 1024, fp) == NULL) {
-	    fprintf(stderr, "\rerror: short read of burn lines\n");
-	    return(-1);
-	 }
-	 sscanf(line, "%d %d %lf\n", &boxbuf[nbox].xfit[i], 
-		&boxbuf[nbox].yfit[i], &boxbuf[nbox].zero[i]);
+      if(boxbuf[nbox].nfit > 0) {
+	 boxbuf[nbox].zero = (double *)calloc(boxbuf[nbox].nfit, sizeof(double));
+	 boxbuf[nbox].xfit = (int *)calloc(boxbuf[nbox].nfit, sizeof(int));
+	 boxbuf[nbox].yfit = (int *)calloc(boxbuf[nbox].nfit, sizeof(int));
+	 for(i=0; i<boxbuf[nbox].nfit; i++) {
+	    if(fgets(line, 1024, fp) == NULL) {
+	       fprintf(stderr, "\rerror: short read of burn lines\n");
+	       return(-1);
+	    }
+	    sscanf(line, "%d %d %lf\n", &boxbuf[nbox].xfit[i], 
+		   &boxbuf[nbox].yfit[i], &boxbuf[nbox].zero[i]);
+	 }
       }
       boxbuf[nbox].fiterr = 0;
@@ -147,8 +148,10 @@
       for(kp=0; kp<n; kp++) {
 	 k = boxid[kp];
-	 zk = box[k].zero[box[k].nfit/2];
+	 zk = 0.0;
+	 if(box[k].nfit > 0) zk = box[k].zero[box[k].nfit/2];
 	 for(jp=kp+1; jp<n; jp++) {
 	    j = boxid[jp];
-	    zj = box[j].zero[box[j].nfit/2];
+	    zj = 0.0;
+	    if(box[j].nfit > 0) zj = box[j].zero[box[j].nfit/2];
 	    if(ABS(yctr[jp]-yctr[kp]) > DIFFERENT_STREAK) {
 /* Trim back the feebler streak */
@@ -238,6 +241,15 @@
 /* First: patched up persists */
       for(k=0; k<cell[j].npersist; k++) {
-	 if(cell[j].persist[k].fiterr) continue;
-	 if(cell[j].persist[k].nfit <= 0) continue;
+
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].persist[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].persist[k].fiterr) continue;
+	       if(cell[j].persist[k].nfit <= 0) continue;
+	    }
+	 } else {
+	    if(cell[j].persist[k].fiterr) continue;
+	    if(cell[j].persist[k].nfit <= 0) continue;
+	 }
 	 fprintf(fp, "%3d %7d  %3d %3d %5d %3d  %3d %3d  %3d %3d  %3d %3d %3d %3d %3d %3d %3d %3d  %1d %1d %9.6f %3d %3d %3d\n",
 		 j, cell[j].persist[k].time, 
@@ -262,7 +274,16 @@
       for(k=0; k<cell[j].nburn; k++) {
 	 if(!cell[j].burn[k].burned) continue;
-	 if(cell[j].burn[k].fiterr && 
-	    cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
-	 if(cell[j].burn[k].nfit <= 0) continue;
+	 if(PERSIST_RETAIN) {
+/* Keep fits which have a dubious slope */
+	    if(cell[j].burn[k].fiterr != FIT_SLOPE_ERROR) {
+	       if(cell[j].burn[k].fiterr && 
+		  cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	       if(cell[j].burn[k].nfit <= 0) continue;
+	    }
+	 } else {
+	    if(cell[j].burn[k].fiterr && 
+	       cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
+	    if(cell[j].burn[k].nfit <= 0) continue;
+	 }
 
 	 i = (cell[j].burn[k].ex - cell[j].burn[k].sx + 1) / 2;
Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/trailfit.c
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/trailfit.c	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/burntool/trailfit.c	(revision 25210)
@@ -226,4 +226,6 @@
 /* FIXME: sanity check fits */
    if(slope >= FIT_MAX_SLOPE || slope < FIT_MIN_SLOPE) {
+      box->slope = slope;
+      box->nfit = 0;
       box->fiterr = FIT_SLOPE_ERROR;
       return(-1);
Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/libfh/fh.c
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/libfh/fh.c	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/libfh/fh.c	(revision 25210)
@@ -1039,4 +1039,5 @@
 	 newval[strlen(newval) - 1] = '\0';
 	 fh_set_str(hu, idx, name, newval, comment);
+	 free(newval);
 	 return;
       }
@@ -1519,4 +1520,29 @@
       i++;
    }
+   return FH_SUCCESS;
+}
+
+static void
+pad_header(HeaderUnit hu, int n)
+{
+   int i;
+   double idx = 900000000;
+
+   for (i = 0; i < n; i++)
+   {
+      fh_set_card(hu, idx++, FH_RESERVE);
+   }
+}
+
+fh_result
+fh_copy(HeaderUnit hu, const HeaderUnit source_)
+{
+   fh_result result;
+   int reserve;
+
+   result = fh_merge(hu, source_);
+   if (result != FH_SUCCESS) return result;
+   reserve = fh_get_reserve(source_);
+   if (reserve) pad_header(hu, reserve);
    return FH_SUCCESS;
 }
@@ -1757,4 +1783,21 @@
 }
 
+int
+fh_get_reserve(HeaderUnit hu)
+{
+   HeaderUnitStruct* list = FH_HU(hu);
+
+   if (!list)
+   {
+      log_error("invalid argument to fh_get_reserve()");
+      return -1;
+   }
+
+   if (list->reserve)
+      return list->reserve;
+   else
+      return list->reserve_found;
+}
+
 fh_result
 fh_rewrite(HeaderUnit hu)
Index: /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/libfh/fh.h
===================================================================
--- /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/libfh/fh.h	(revision 25209)
+++ /branches/czw_branch/cleanup/extsrc/gpcsw/gpcsrc/fits/libfh/fh.h	(revision 25210)
@@ -174,4 +174,9 @@
  * is used to create a new FITS header.  NOT for use with fh_rewrite().
  */
+int fh_get_reserve(HeaderUnit hu);
+/*
+ * Get the current setting or the number of reserve cards found in
+ * a header unit.  Returns -1 if hu is invalid.
+ */
 fh_result fh_validate(HeaderUnit hu); /* fh_validate.c; for use by fhtool.c */
 
@@ -386,4 +391,5 @@
 double fh_idx(HeaderUnit hu); /* idx of the last card returned by fh_next */
 fh_result fh_merge(HeaderUnit hu, const HeaderUnit source); /* source unchanged */
+fh_result fh_copy(HeaderUnit hu, const HeaderUnit source); /* fh_merge+keep reserve */
 
 /* ---------------------------------------------------------
@@ -459,4 +465,3 @@
  */
 
-
 #endif /* _INCLUDED_fh */
Index: /branches/czw_branch/cleanup/ippTools/src/pxchip.c
===================================================================
--- /branches/czw_branch/cleanup/ippTools/src/pxchip.c	(revision 25209)
+++ /branches/czw_branch/cleanup/ippTools/src/pxchip.c	(revision 25210)
@@ -69,10 +69,6 @@
     psMetadataAddF64(md,  PS_LIST_TAIL, "-posang_min",         0, "search by min rotator position angle", NAN);
     psMetadataAddF64(md,  PS_LIST_TAIL, "-posang_max",         0, "search by max rotator position angle", NAN);
-<<<<<<< .mine
-=======
     psMetadataAddF32(md,  PS_LIST_TAIL, "-sun_angle_min",         0, "search by min solar angle", NAN);
     psMetadataAddF32(md,  PS_LIST_TAIL, "-sun_angle_max",         0, "search by max solar angle", NAN);
-    psMetadataAddStr(md,  PS_LIST_TAIL, "-object",             0, "search by exposure object", NULL);
->>>>>>> .r25099
     psMetadataAddStr(md,  PS_LIST_TAIL, "-object",             0, "search by exposure object", NULL);
     psMetadataAddStr(md,  PS_LIST_TAIL, "-comment",            0, "search by comment field (LIKE comparison)", NULL);
Index: /branches/czw_branch/cleanup/ippconfig/recipes/masks.16bit.config
===================================================================
--- /branches/czw_branch/cleanup/ippconfig/recipes/masks.16bit.config	(revision 25209)
+++ /branches/czw_branch/cleanup/ippconfig/recipes/masks.16bit.config	(revision 25210)
@@ -20,4 +20,5 @@
 
 # Mask values which represent non-astronomical structures
+BURNTOOL        U16     0x0080          # Pixel may contain uncorrected streak.
 CR		U16	0x0100		# Pixel contains a cosmic ray
 SPIKE		U16	0x0200		# Pixel contains a diffraction spike
Index: /branches/czw_branch/cleanup/ippconfig/recipes/ppImage.config
===================================================================
--- /branches/czw_branch/cleanup/ippconfig/recipes/ppImage.config	(revision 25209)
+++ /branches/czw_branch/cleanup/ippconfig/recipes/ppImage.config	(revision 25210)
@@ -16,4 +16,5 @@
 MASK.SATURATED     BOOL    TRUE            # Mask the saturated pixels
 MASK.LOW           BOOL    TRUE            # Mask pixels below valid range
+MASK.BURNTOOL      BOOL    TRUE            # Mask potential burntool trails
 VARIANCE.BUILD     BOOL    FALSE           # Build internal variance image
 PATTERN            BOOL    FALSE           # Fit and remove pattern noise?
@@ -54,4 +55,6 @@
 ## if we use multithreaded detrending, detrend this number of rows per thread
 SCAN.ROWS        S32     100
+
+BURNTOOL.TRAILS U16 0x01
 
 # Non-linearity correction
Index: /branches/czw_branch/cleanup/ppImage/src/ppImage.h
===================================================================
--- /branches/czw_branch/cleanup/ppImage/src/ppImage.h	(revision 25209)
+++ /branches/czw_branch/cleanup/ppImage/src/ppImage.h	(revision 25210)
@@ -26,4 +26,5 @@
     bool doMaskBuild;                   // Build internal mask
     bool doVarianceBuild;               // Build internal variance map
+    bool doMaskBurntool;                // mask potential burntool trails
     bool doMaskSat;                     // mask saturated pixels
     bool doMaskLow;                     // mask low pixels
@@ -74,5 +75,5 @@
     psImageMaskType darkMask;           // Mask value to give bad dark pixels
     psImageMaskType blankMask;          // Mask value to give blank pixels
-
+    psImageMaskType burntoolMask;       // Suspect pixels that fall where a burntool trail is expected.
     // non-linear correction parameters
     psDataType nonLinearType;
@@ -82,5 +83,5 @@
     // options for the analysis
     pmOverscanOptions *overscan;        // Overscan options
-
+    int burntoolTrails;
     // binning parameters
     int xBin1;                          // x-binning, scale 1
@@ -156,4 +157,6 @@
 bool ppImageCheckCTE(pmConfig *config, ppImageOptions *options, pmFPAview *view);
 
+bool ppImageBurntoolMask(pmConfig *config, ppImageOptions *options, pmFPAview *view, pmReadout *mask);
+
 // Record which detrend file was used for the detrending
 bool ppImageDetrendRecord(
Index: /branches/czw_branch/cleanup/ppImage/src/ppImageBurntoolMask.c
===================================================================
--- /branches/czw_branch/cleanup/ppImage/src/ppImageBurntoolMask.c	(revision 25209)
+++ /branches/czw_branch/cleanup/ppImage/src/ppImageBurntoolMask.c	(revision 25210)
@@ -3,9 +3,12 @@
 #endif
 
+#define PPIMAGE_BURNTOOL_DEBUG 1
+
 #include "ppImage.h"
 
-bool ppImageBurntoolMask (pmConfig *config, ppImageOptions *options, pmFPAview *view) {
-
+bool ppImageBurntoolMask (pmConfig *config, ppImageOptions *options, pmFPAview *view,pmReadout *mask) {
   bool status = true;
+  int burntool_cell;
+  /* Find input filename */
   pmFPAfile *inputFile = psMetadataLookupPtr(&status , config->files, "PPIMAGE.INPUT");
   if (!status) {
@@ -13,7 +16,9 @@
     return(false);
   }
-
   psFits *fits = inputFile->fits;
 
+  /* Read input header, and find the burntool data table. */
+  psMetadata *phu = psFitsReadHeader(NULL, fits);
+  
   if (!psFitsMoveExtName(fits,"burntool_areas")) {
     psError(PS_ERR_IO,false, "Unable to find extension burntool_areas");
@@ -21,21 +26,44 @@
   }
   long Nrows = psFitsTableSize(fits);  
+
   long row = 0;
-  
-  pmFPAview *detview = pmFPAviewAlloc(0);
-  *detview = *view;
-  detview->readout = 0;
-  pmReadout *mask = pmFPAfileThisReadout(config->files,detview,"PPIMAGE.MASK");
+
+  psLogMsg ("ppImageBurntoolMask", 4, "Inside burntool mask %ld", Nrows);
+
+  /* Redirects and Memory juggling. */
+  view->readout = 0;
   psImage *image = mask->mask;
 
-  psImageMaskType maskValue = psMetadataLookupS32(&status,config->files,"PPIMAGE.BURNTOOL_MASK");
   
+  /* Set the maskValue from the recipes. */
+  psImageMaskType maskValue = options->burntoolMask;
+#ifdef PPIMAGE_BURNTOOL_DEBUG
+  psLogMsg("ppImageBurntoolMask", 4, "Status: %ld %d\n",Nrows,maskValue);
+#endif
+
+  burntool_cell = view->cell;
+  burntool_cell = (view->cell % 8) * 8 + (view->cell - (view->cell % 8)) / 8;
+  psLogMsg("ppImageBurntoolMask", 4, "Cell mapping: %d %d %d\n",view->cell,burntool_cell,-1);
   for (row = 0; row < Nrows; row++) {
     psMetadata *rowMD = psFitsReadTableRow(fits,row);
 
-    if (psMetadataLookupS32(&status,rowMD,"cell") == detview->cell) {
-
-      if (psMetadataLookupS32(&status,rowMD,"func") != -1) { // This should be an actual check
-
+    if (psMetadataLookupS32(&status,rowMD,"cell") == burntool_cell) {
+      if (((options->burntoolTrails & 0x01)&&(psMetadataLookupS32(&status,rowMD,"nfit") == 0))||
+	  ((options->burntoolTrails & 0x02)&&(psMetadataLookupS32(&status,rowMD,"up") == 1))||
+	  ((options->burntoolTrails & 0x04)&&(psMetadataLookupS32(&status,rowMD,"up") == 0))) {
+	/*       If the fit fails, burntool reports zero here.  This
+		 signifies that it expected to see a trail (else why
+		 fit) but did not find it when it attempted to
+		 correct. */
+#ifdef PPIMAGE_BURNTOOL_DEBUG
+	psLogMsg ("ppImageBurntoolMask", 4, "Masking! %d (%d %d %d) %d %d",
+		  psMetadataLookupS32(&status,rowMD,"cell"),
+		  ((options->burntoolTrails & 0x0001)&&(psMetadataLookupS32(&status,rowMD,"nfit") == 0)),
+		  ((options->burntoolTrails & 0x02)&&(psMetadataLookupS32(&status,rowMD,"up") == 1)),
+		  ((options->burntoolTrails & 0x04)&&(psMetadataLookupS32(&status,rowMD,"up") == 0)),
+		  options->burntoolTrails,
+		  maskValue
+		  );
+#endif
 	for (int i = psMetadataLookupS32(&status,rowMD,"sxfit");
 	     i <= psMetadataLookupS32(&status,rowMD,"exfit");
@@ -44,4 +72,8 @@
 	  if (psMetadataLookupS32(&status,rowMD,"up") == 0) {
 	    for (int j = 0; j <= psMetadataLookupS32(&status,rowMD,"y1p"); j++) {
+/* #ifdef PPIMAGE_BURNTOOL_DEBUG */
+/* 	      psLogMsg("ppImageBurntoolMask", 4, "Noisy!: %d %d %d %d\n", */
+/* 		       i,j,image->data.PS_TYPE_IMAGE_MASK_DATA[j][i],maskValue); */
+/* #endif */
 	      image->data.PS_TYPE_IMAGE_MASK_DATA[j][i] |= maskValue;
 	    }
@@ -49,4 +81,8 @@
 	  else {
 	    for (int j = psMetadataLookupS32(&status,rowMD,"y1m"); j < image->numRows ; j++) {
+/* #ifdef PPIMAGE_BURNTOOL_DEBUG */
+/* 	      psLogMsg("ppImageBurntoolMask", 4, "Noisy!: %d %d %d %d\n", */
+/* 		       i,j,image->data.PS_TYPE_IMAGE_MASK_DATA[j][i],maskValue); */
+/* #endif */
 	      image->data.PS_TYPE_IMAGE_MASK_DATA[j][i] |= maskValue;
 	    }
@@ -56,6 +92,7 @@
       }
     }
+    psFree(rowMD);
   }
-
+  psFree(phu);
   return(status);
 }
Index: /branches/czw_branch/cleanup/ppImage/src/ppImageDetrendReadout.c
===================================================================
--- /branches/czw_branch/cleanup/ppImage/src/ppImageDetrendReadout.c	(revision 25209)
+++ /branches/czw_branch/cleanup/ppImage/src/ppImageDetrendReadout.c	(revision 25210)
@@ -26,4 +26,8 @@
         pmMaskBadPixels(input, mask, options->maskValue);
     }
+    if (options->doMaskBurntool) {
+      ppImageBurntoolMask(config,options,view,input);
+    }
+
 
 # if 0
Index: /branches/czw_branch/cleanup/ppImage/src/ppImageOptions.c
===================================================================
--- /branches/czw_branch/cleanup/ppImage/src/ppImageOptions.c	(revision 25209)
+++ /branches/czw_branch/cleanup/ppImage/src/ppImageOptions.c	(revision 25210)
@@ -21,4 +21,5 @@
     options->doMaskSat       = false;   // mask saturated pixels
     options->doMaskLow       = false;   // mask low pixels
+    options->doMaskBurntool  = false;   // mask potential burntool trails
     options->doVarianceBuild = false;   // Build internal variance
     options->doMask          = false;   // Mask bad pixels
@@ -64,5 +65,6 @@
     options->blankMask       = 0x00;    // Blank (no data, cell gap) pixels (supplied to pmChipMosaic, pmFPAMosaic)
     options->markValue       = 0x00;    // A safe bit for internal marking
-
+    options->burntoolMask    = 0x00;    // Suspect pixels that fall where a burntool trail is expected.
+    options->burntoolTrails  = 0x00;    // Which types of burntool areas to mask.
     // crosstalk options
     options->doCrosstalkMeasure = false;   // measure crosstalk
@@ -219,4 +221,5 @@
     options->doMaskSat   = psMetadataLookupBool(NULL, recipe, "MASK.SATURATED");
     options->doMaskLow   = psMetadataLookupBool(NULL, recipe, "MASK.LOW");
+    options->doMaskBurntool = psMetadataLookupBool(NULL, recipe, "MASK.BURNTOOL");
     options->doVarianceBuild = psMetadataLookupBool(NULL, recipe, "VARIANCE.BUILD");
 
@@ -245,13 +248,19 @@
     options->applyParity = psMetadataLookupBool(NULL, recipe, "APPLY.CELL.PARITY");
 
+    options->burntoolTrails = psMetadataLookupU16(&status, recipe, "BURNTOOL.TRAILS");
+    if (!status) {
+      psWarning("BURNTOOL.TRAILS not found in recipe: setting to default value.\n");
+    }
+    
     // binned image options
     options->xBin1 = psMetadataLookupS32(&status, recipe, "BIN1.XBIN");
     if (!status) {
         psWarning("BIN1.XBIN not found in recipe: setting to default value.\n");
+	options->xBin1 = 4;
     }
     options->yBin1 = psMetadataLookupS32(&status, recipe, "BIN1.YBIN");
     if (!status) {
         psWarning("BIN1.YBIN not found in recipe: setting to default value.\n");
-        options->yBin1 = 16;
+        options->yBin1 = 4;
     }
 
Index: /branches/czw_branch/cleanup/ppImage/src/ppImageSetMaskBits.c
===================================================================
--- /branches/czw_branch/cleanup/ppImage/src/ppImageSetMaskBits.c	(revision 25209)
+++ /branches/czw_branch/cleanup/ppImage/src/ppImageSetMaskBits.c	(revision 25210)
@@ -38,4 +38,8 @@
     psAssert (options->lowMask, "low mask not set");
 
+    // mask for suspect regions due to burntool
+    options->burntoolMask = pmConfigMaskGet("BURNTOOL",config);
+    psAssert (options->burntoolMask, "burntool mask not set");
+    
     // save MASK and MARK on the PSPHOT recipe
     psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
