Index: /trunk/ppSub/src/ppSubArguments.c
===================================================================
--- /trunk/ppSub/src/ppSubArguments.c	(revision 14672)
+++ /trunk/ppSub/src/ppSubArguments.c	(revision 14673)
@@ -199,4 +199,10 @@
     psMetadataAddBool(arguments,  PS_LIST_TAIL, "-generate-mask", 0, "Generate mask if not supplied?", false);
     psMetadataAddStr(arguments,  PS_LIST_TAIL, "-stamps", 0, "Stamps filename; file has x,y on each line", NULL);
+    psMetadataAddBool(arguments, PS_LIST_TAIL, "-opt", 0, "Derive optimum parameters for ISIS kernels?", false);
+    psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-min", 0, "Minimum value for optimum kernel search", NAN);
+    psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-max", 0, "Minimum value for optimum kernel search", NAN);
+    psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-step", 0, "Step value for optimum kernel search", NAN);
+    psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-tol", 0, "Tolerance for optimum kernel search", NAN);
+    psMetadataAddS32(arguments, PS_LIST_TAIL, "-opt-order", 0, "Maximum order for optimum kernel search", -1);
 
     if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 4) {
@@ -260,4 +266,14 @@
     }
 
+    if (psMetadataLookupBool(NULL, arguments, "-opt") || psMetadataLookupBool(NULL, recipe, "OPTIMUM")) {
+        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "OPTIMUM", 0,
+                          "Derive optimum parameters for ISIS kernels?", true);
+        VALUE_ARG_RECIPE_FLOAT("-opt-min", "OPTIMUM.MIN",   F32);
+        VALUE_ARG_RECIPE_FLOAT("-opt-max", "OPTIMUM.MAX",   F32);
+        VALUE_ARG_RECIPE_FLOAT("-opt-step","OPTIMUM.STEP",  F32);
+        VALUE_ARG_RECIPE_FLOAT("-opt-tol", "OPTIMUM.TOL",   F32);
+        VALUE_ARG_RECIPE_INT("-opt-order", "OPTIMUM.ORDER", S32, -1);
+    }
+
     psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REVERSE", 0, "Reverse sense of subtraction",
                       psMetadataLookupBool(NULL, arguments, "-reverse"));
Index: /trunk/ppSub/src/ppSubReadout.c
===================================================================
--- /trunk/ppSub/src/ppSubReadout.c	(revision 14672)
+++ /trunk/ppSub/src/ppSubReadout.c	(revision 14673)
@@ -52,4 +52,11 @@
     const char *stampsName = psMetadataLookupStr(&mdok, config->arguments, "STAMPS"); // Filename for stamps
 
+    bool optimum = psMetadataLookupBool(&mdok, config->arguments, "OPTIMUM"); // Derive optimum parameters?
+    float optMin = psMetadataLookupF32(&mdok, config->arguments, "OPTIMUM.MIN"); // Minimum width for search
+    float optMax = psMetadataLookupF32(&mdok, config->arguments, "OPTIMUM.MAX"); // Maximum width for search
+    float optStep = psMetadataLookupF32(&mdok, config->arguments, "OPTIMUM.STEP"); // Step for search
+    float optThresh = psMetadataLookupF32(&mdok, config->arguments, "OPTIMUM.TOL"); // Tolerance for search
+    int optOrder = psMetadataLookupS32(&mdok, config->arguments, "OPTIMUM.ORDER"); // Order for search
+
     // Generate masks if they don't exist
     int numCols = input->numCols, numRows = input->numRows; // Image dimensions
@@ -71,12 +78,17 @@
     }
 
+    psVector *optWidths = NULL;         // Vector with FWHMs for optimum search
+    if (optimum) {
+        optWidths = psVectorCreate(optWidths, optMin, optMax, optStep, PS_TYPE_F32);
+    }
+
     if (!pmSubtractionMatch(outRO, refRO, inRO, footprint, regionSize, spacing, threshold, stampsName,
-                            NAN, type, size, order, widths, orders, inner, ringsOrder, binning, iter,
-                            rej, maskBad, maskBlank)) {
+                            NAN, type, size, order, widths, orders, inner, ringsOrder, binning, optimum,
+                            optWidths, optOrder, optThresh, iter, rej, maskBad, maskBlank)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to match images.");
         psFree(outRO);
         return false;
     }
-
+    psFree(optWidths);
 
     // Add kernel descrption to header
