Index: trunk/ppSub/src/ppSub.c
===================================================================
--- trunk/ppSub/src/ppSub.c	(revision 29003)
+++ trunk/ppSub/src/ppSub.c	(revision 29551)
@@ -109,4 +109,5 @@
         pmModelClassCleanup();
         pmConfigDone();
+	pmVisualCleanup ();
         psLibFinalize();
 
Index: trunk/ppSub/src/ppSubConvolve.c
===================================================================
--- trunk/ppSub/src/ppSubConvolve.c	(revision 29003)
+++ trunk/ppSub/src/ppSubConvolve.c	(revision 29551)
@@ -241,4 +241,15 @@
             psThreadPoolInit(threads);
         }
+
+	// Mask the NAN values (USE BLANK instead of SAT?)
+	if (!pmReadoutMaskInvalid(input, maskVal, maskBad)) {
+	  psError(PPSUB_ERR_DATA, false, "Unable to mask non-finite pixels in input.");
+	  return false;
+	}
+	if (!pmReadoutMaskInvalid(ref, maskVal, maskBad)) {
+	  psError(PPSUB_ERR_DATA, false, "Unable to mask non-finite pixels in reference.");
+	  return false;
+	}
+
         if (!pmSubtractionMatchPrecalc(inConv, refConv, input, ref, inRO->analysis,
                                        stride, kernelErr, covarFrac, maskVal, maskBad, maskPoor,
Index: trunk/ppSub/src/ppSubMatchPSFs.c
===================================================================
--- trunk/ppSub/src/ppSubMatchPSFs.c	(revision 29003)
+++ trunk/ppSub/src/ppSubMatchPSFs.c	(revision 29551)
@@ -110,4 +110,5 @@
     pmReadout *kernelRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT.KERNELS"); // RO with kernel
     if (kernelRO) {
+	psAbort("we probably need to set the FWHM values");
         psFree(view);
         return true;
@@ -117,9 +118,4 @@
     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
     psAssert(recipe, "We checked this earlier, so it should be here.");
-    if (!psMetadataLookupBool(NULL, recipe, "SCALE")) {
-        // No scaling requested
-        psFree(view);
-        return true;
-    }
 
     // Input images
@@ -131,6 +127,6 @@
     pmReadout *refSourceRO = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.SOURCES");
     if (!inSourceRO || !refSourceRO) {
-        psWarning("Unable to scale kernel, since no sources were provided.");
-        return true;
+        psError(PPSUB_ERR_DATA, false, "Unable to scale kernel, since no sources were provided.");
+        return false;
     }
 
@@ -141,6 +137,6 @@
 
     if (!inDetections || !refDetections) {
-        psWarning("Unable to scale kernel, since no sources were provided.");
-        return true;
+        psError(PPSUB_ERR_DATA, false, "Unable to set FWHM or scale kernel, since no sources were provided.");
+        return false;
     }
 
@@ -161,5 +157,15 @@
     psLogMsg("ppSub", PS_LOG_INFO, "Input FWHM: %f\nReference FWHM: %f\n", inFWHM, refFWHM);
     if (!isfinite(inFWHM) || !isfinite(refFWHM)) {
-        psWarning("Unable to scale kernel, since unable to measure PSFs.");
+        psError(PPSUB_ERR_DATA, false, "Cannot determine FHWM for images, giving up.");
+        return false;
+    }
+
+    // we need to register the FWHM values for use downstream 
+    pmSubtractionSetFWHMs(inFWHM, refFWHM);
+
+    // is auto-scaling needed?
+    if (!psMetadataLookupBool(NULL, recipe, "SCALE")) {
+        // No scaling requested
+        psFree(view);
         return true;
     }
@@ -175,6 +181,5 @@
     }
 
-    if (!pmSubtractionParamsScale(kernelSize, stampSize, kernelWidths, inFWHM, refFWHM,
-                                  scaleRef, scaleMin, scaleMax)) {
+    if (!pmSubtractionParamsScale(kernelSize, stampSize, kernelWidths, scaleRef, scaleMin, scaleMax)) {
         psError(PPSUB_ERR_DATA, false, "Unable to scale parameters.");
         return false;
@@ -184,4 +189,15 @@
 }
 
+pmSubtractionMode subModeFromString (char *string) {
+
+    if (!strcasecmp(string, "AUTO")) return PM_SUBTRACTION_MODE_UNSURE;
+    if (!strcasecmp(string, "DUAL")) return PM_SUBTRACTION_MODE_DUAL;
+    if (!strcasecmp(string, "SINGLE1")) return PM_SUBTRACTION_MODE_1;
+    if (!strcasecmp(string, "SINGLE2")) return PM_SUBTRACTION_MODE_2;
+    if (!strcasecmp(string, "1")) return PM_SUBTRACTION_MODE_1;
+    if (!strcasecmp(string, "2")) return PM_SUBTRACTION_MODE_2;
+
+    return PM_SUBTRACTION_MODE_UNSURE;
+}
 
 bool ppSubMatchPSFs(ppSubData *data)
@@ -317,4 +333,16 @@
     psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask for bad pixels
 
+    // we have three things to control the convolution choice:
+
+    // 1) in the recipe, the keyword DUAL can be TRUE or FALSE.  if TRUE, DUAL is used. If not
+    // DUAL, then we are doing SINGLE convolution (but see CONVOLVE.TARGET below).
+
+    // 2) if the -convolve option is given on the command line, the specified input (1 or 2) is
+    // the one convolved.  Allowed values are 1 or 2.
+
+    // 3) if the -convolve option is NOT given, then the value of the recipe keyword
+    // CONVOLVE.TARGET is used.  this may have the value DUAL, AUTO, SINGLE1, SINGLE2, 1, 2.
+    // thus, DUAL convolution can be turned on with either DUAL = T or CONVOLVE.TARGET = DUAL
+
     bool dual = psMetadataLookupBool(&mdok, recipe, "DUAL"); // Dual convolution?
     pmSubtractionMode subMode;          // Subtraction mode
@@ -322,19 +350,21 @@
         subMode = PM_SUBTRACTION_MODE_DUAL;
     } else {
-        int convolve = psMetadataLookupS32(NULL, config->arguments, "-convolve"); // Image number to convolve
-        switch (convolve) {
-          case 0:
-            subMode = PM_SUBTRACTION_MODE_UNSURE;
-            break;
-          case 1:
-            subMode = PM_SUBTRACTION_MODE_1;
-            break;
-          case 2:
-            subMode = PM_SUBTRACTION_MODE_2;
-            break;
-          default:
-            psError(PPSUB_ERR_ARGUMENTS, false, "Invalid value for -convolve");
-            return false;
-        }
+	char *convolveName = psMetadataLookupStr(&mdok, recipe, "CONVOLVE.TARGET"); // recipe value for target
+        int convolve = psMetadataLookupS32(&mdok, config->arguments, "-convolve"); // override with command-line option
+	switch (convolve) {
+	  case 0:
+	    // convolve is 0 if it is not supplied on the command line
+	    subMode = subModeFromString(convolveName);
+	    break;
+	  case 1:
+	    subMode = PM_SUBTRACTION_MODE_1;
+	    break;
+	  case 2:
+	    subMode = PM_SUBTRACTION_MODE_2;
+	    break;
+	  default:
+	    psError(PPSUB_ERR_ARGUMENTS, false, "Invalid value for -convolve");
+	    return false;
+	}
     }
 
Index: trunk/ppSub/src/ppSubSetMasks.c
===================================================================
--- trunk/ppSub/src/ppSubSetMasks.c	(revision 29003)
+++ trunk/ppSub/src/ppSubSetMasks.c	(revision 29551)
@@ -77,14 +77,13 @@
     }
 
-    // Mask the NAN values
-    if (!pmReadoutMaskNonfinite(inRO, satValue)) {
+    // Mask the NAN values (USE BLANK instead of SAT?)
+    if (!pmReadoutMaskInvalid(inRO, maskValue, satValue)) {
         psError(PPSUB_ERR_DATA, false, "Unable to mask non-finite pixels in input.");
         return false;
     }
-    if (!pmReadoutMaskNonfinite(refRO, satValue)) {
+    if (!pmReadoutMaskInvalid(refRO, maskValue, satValue)) {
         psError(PPSUB_ERR_DATA, false, "Unable to mask non-finite pixels in reference.");
         return false;
     }
-
 
 #if 0
