Index: /trunk/ppStack/src/ppStackArguments.c
===================================================================
--- /trunk/ppStack/src/ppStackArguments.c	(revision 18917)
+++ /trunk/ppStack/src/ppStackArguments.c	(revision 18918)
@@ -49,5 +49,5 @@
         } \
     } \
-    psMetadataAdd##TYPE(config->arguments, PS_LIST_TAIL, RECIPENAME, 0, NULL, value); \
+    psMetadataAdd##TYPE(recipe, PS_LIST_TAIL, RECIPENAME, PS_META_REPLACE, NULL, value); \
 }
 
@@ -64,5 +64,5 @@
         } \
     } \
-    psMetadataAdd##TYPE(config->arguments, PS_LIST_TAIL, RECIPENAME, 0, NULL, value); \
+    psMetadataAdd##TYPE(recipe, PS_LIST_TAIL, RECIPENAME, PS_META_REPLACE, NULL, value); \
 }
 
@@ -80,5 +80,5 @@
     } \
     psMaskType value = pmConfigMaskGet(name, config); \
-    psMetadataAddU8(config->arguments, PS_LIST_TAIL, RECIPENAME, 0, NULL, value); \
+    psMetadataAddU8(recipe, PS_LIST_TAIL, RECIPENAME, PS_META_REPLACE, NULL, value); \
 }
 
@@ -94,5 +94,6 @@
         } \
     } \
-    psMetadataAddS32(config->arguments, PS_LIST_TAIL, RECIPENAME, 0, NULL, psStatsOptionFromString(stat)); \
+    psMetadataAddS32(recipe, PS_LIST_TAIL, RECIPENAME, PS_META_REPLACE, \
+                     NULL, psStatsOptionFromString(stat)); \
 }
 
@@ -106,5 +107,5 @@
     psString value = psMetadataLookupStr(NULL, arguments, argName); // Value of interest
     if (value && strlen(value) > 0) {
-        return psMetadataAddStr(target, PS_LIST_TAIL, mdName, 0, NULL, value);
+        return psMetadataAddStr(target, PS_LIST_TAIL, mdName, PS_META_REPLACE, NULL, value);
     }
     return false;
@@ -128,5 +129,5 @@
         }
     }
-    return psMetadataAddStr(target, PS_LIST_TAIL, mdName, 0, NULL, value);
+    return psMetadataAddStr(target, PS_LIST_TAIL, mdName, PS_META_REPLACE, NULL, value);
 }
 
@@ -142,17 +143,21 @@
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-stats", 0, "Statistics file", NULL);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-iter", 0, "Number of rejection iterations", 0);
-    psMetadataAddF32(arguments, PS_LIST_TAIL, "-combine-rej", 0, "Combination rejection thresold (sigma)", NAN);
+    psMetadataAddF32(arguments, PS_LIST_TAIL, "-combine-rej", 0,
+                     "Combination rejection thresold (sigma)", NAN);
     psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-bad", 0, "Mask value for bad pixels", 0);
     psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-blank", 0, "Mask value for blank region", 0);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-threshold-mask", 0, "Threshold for mask deconvolution", NAN);
-    psMetadataAddF32(arguments, PS_LIST_TAIL, "-image-rej", 0, "Pixel rejection fraction threshold for rejecting entire image", NAN);
+    psMetadataAddF32(arguments, PS_LIST_TAIL, "-image-rej", 0,
+                     "Pixel rejection fraction threshold for rejecting entire image", NAN);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-rows", 0, "Rows to read at once", 0);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-photometry", 0, "Do photometry on stacked image?", false);
-    psMetadataAddS32(arguments, PS_LIST_TAIL, "-psf-instances", 0, "Number of instances for PSF generation", 0);
+    psMetadataAddS32(arguments, PS_LIST_TAIL, "-psf-instances", 0,
+                     "Number of instances for PSF generation", 0);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-psf-radius", 0, "Radius for PSF generation", NAN);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-psf-model", 0, "Model name for PSF generation", "PS_MODEL_RGAUSS");
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-psf-model", 0, "Model name for PSF generation", NULL);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-psf-order", 0, "Spatial order for PSF generation", 0);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-variance", 0, "Use variance for rejection?", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-safe", 0, "Play safe with small numbers of pixels to combine?", false);
+    psMetadataAddBool(arguments, PS_LIST_TAIL, "-safe", 0,
+                      "Play safe with small numbers of pixels to combine?", false);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-source-radius", 0, "Source exclusion radius", NAN);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-source-iter", 0, "Source clipping iterations", 0);
@@ -160,11 +165,14 @@
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-source-min", 0, "Source minimum overlap", 0);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-renorm", 0, "Renormalise variance maps?", false);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-mean", 0, "Statistic for mean in renormalisation", NULL);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-stdev", 0, "Statistic for stdev in renormalisation", NULL);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-mean", 0,
+                     "Statistic for mean in renormalisation", NULL);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-stdev", 0,
+                     "Statistic for stdev in renormalisation", NULL);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-renorm-width", 0, "Width of renormalisation boxes", 0);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-image", 0, "Suffix for temporary images", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-mask", 0, "Suffix for temporary masks", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-weight", 0, "Suffix for temporary weight maps", NULL);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-temp-delete", 0, "Delete temporary files on completion?", false);
+    psMetadataAddBool(arguments, PS_LIST_TAIL, "-temp-delete", 0,
+                      "Delete temporary files on completion?", false);
 
     if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 3) {
@@ -173,9 +181,5 @@
 
     const char *stampsName = psMetadataLookupStr(NULL, arguments, "-stamps"); // Name of stamps file
-    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "STAMPS", 0, "Stamps file", stampsName);
-    // if (!stampsName && !psMetadataLookupPtr(&mdok, config->arguments, "PPSTACK.SOURCES")) {
-    // psError(PS_ERR_BAD_PARAMETER_VALUE, true, "One of -sources or -stamps must be specified.");
-    //goto ERROR;
-    // }
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "STAMPS", 0, "Stamps file", stampsName);
 
     unsigned int numBad = 0;                     // Number of bad lines
@@ -185,16 +189,13 @@
         return false;
     }
-    psMetadataAddMetadata(config->arguments, PS_LIST_TAIL, "INPUTS", 0,
-                          "Metadata with input details", inputs);
+    psMetadataAddMetadata(arguments, PS_LIST_TAIL, "INPUTS", 0, "Metadata with input details", inputs);
     psFree(inputs);
-    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0,
-                     "Root name of the output image list", argv[2]);
-
-    valueArgStr(arguments, "-stats", "STATS", config->arguments);
-
-    if (psMetadataLookupBool(NULL, arguments, "-photometry")) {
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "PHOTOMETRY", PS_META_REPLACE,
-                          "Do photometry on stacked image?", true);
-    }
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "OUTPUT", 0, "Root name of the output image list", argv[2]);
+
+    valueArgStr(arguments, "-stats", "STATS", arguments);
+
+    psMetadataAddBool(arguments, PS_LIST_TAIL, "PHOTOMETRY", PS_META_REPLACE,
+                      "Do photometry on stacked image?",
+                      psMetadataLookupBool(NULL, arguments, "-photometry"));
 
     return true;
@@ -207,5 +208,5 @@
     psMetadata *arguments = config->arguments; // Command-line arguments
 
-    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppSim
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe
     if (!recipe) {
         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSTACK_RECIPE);
@@ -229,9 +230,9 @@
     VALUE_ARG_RECIPE_FLOAT("-psf-radius",  "PSF.RADIUS",    F32);
     VALUE_ARG_RECIPE_INT("-psf-order",     "PSF.ORDER",     S32, 0);
-    valueArgStr(arguments, "-psf-model", "PSF.MODEL", config->arguments);
+    valueArgRecipeStr(arguments, recipe, "-psf-model", "PSF.MODEL", recipe);
 
     if (psMetadataLookupBool(NULL, arguments, "-photometry") ||
         psMetadataLookupBool(NULL, recipe, "PHOTOMETRY")) {
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "PHOTOMETRY", PS_META_REPLACE,
+        psMetadataAddBool(arguments, PS_LIST_TAIL, "PHOTOMETRY", PS_META_REPLACE,
                           "Do photometry on stacked image?", true);
     }
@@ -239,11 +240,10 @@
     if (psMetadataLookupBool(NULL, arguments, "-variance") ||
         psMetadataLookupBool(NULL, recipe, "VARIANCE")) {
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "VARIANCE", 0,
-                          "Use variance for rejection?", true);
+        psMetadataAddBool(arguments, PS_LIST_TAIL, "VARIANCE", 0, "Use variance for rejection?", true);
     }
 
     if (psMetadataLookupBool(NULL, arguments, "-safe") ||
         psMetadataLookupBool(NULL, recipe, "SAFE")) {
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "SAFE", 0,
+        psMetadataAddBool(arguments, PS_LIST_TAIL, "SAFE", 0,
                           "Play safe with small number of pixels to combine?", true);
     }
@@ -251,5 +251,5 @@
     if (psMetadataLookupBool(NULL, arguments, "-renorm") ||
         psMetadataLookupBool(NULL, recipe, "RENORM")) {
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "RENORM", 0, "Renormalise variance maps?", true);
+        psMetadataAddBool(arguments, PS_LIST_TAIL, "RENORM", 0, "Renormalise variance maps?", true);
     }
     VALUE_ARG_RECIPE_INT("-renorm-width", "RENORM.WIDTH", S32, 0);
@@ -257,15 +257,28 @@
     VALUE_ARG_RECIPE_STAT("-renorm-stdev", "RENORM.STDEV");
 
-    valueArgRecipeStr(arguments, recipe, "-temp-image",  "TEMP.IMAGE",  config->arguments);
-    valueArgRecipeStr(arguments, recipe, "-temp-mask",   "TEMP.MASK",   config->arguments);
-    valueArgRecipeStr(arguments, recipe, "-temp-weight", "TEMP.WEIGHT", config->arguments);
+    valueArgRecipeStr(arguments, recipe, "-temp-image",  "TEMP.IMAGE",  recipe);
+    valueArgRecipeStr(arguments, recipe, "-temp-mask",   "TEMP.MASK",   recipe);
+    valueArgRecipeStr(arguments, recipe, "-temp-weight", "TEMP.WEIGHT", recipe);
 
     if (psMetadataLookupBool(NULL, arguments, "-temp-delete") ||
         psMetadataLookupBool(NULL, recipe, "TEMP.DELETE")) {
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "TEMP.DELETE", 0,
+        psMetadataAddBool(arguments, PS_LIST_TAIL, "TEMP.DELETE", 0,
                           "Delete temporary files on completion?", true);
     }
 
-    psTrace("ppStack", 1, "Done reading command-line arguments\n");
+    psTrace("ppStack", 1, "Done parsing arguments\n");
+
+    // Dump configuration, now that's it's settled
+    {
+        pmConfigCamerasCull(config);
+        pmConfigRecipesCull(config, "PPSTACK,PPSUB,PPSTATS,PSPHOT,MASKS");
+
+        const char *outroot = psMetadataLookupStr(NULL, arguments, "OUTPUT"); // Output root name
+        psAssert(outroot, "Should be there, we put it there!");
+
+        pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PPSTACK.INPUT"); // Input file
+        pmConfigDump(config, input->fpa, outroot);
+    }
+
     return true;
 
Index: /trunk/ppStack/src/ppStackLoop.c
===================================================================
--- /trunk/ppStack/src/ppStackLoop.c	(revision 18917)
+++ /trunk/ppStack/src/ppStackLoop.c	(revision 18918)
@@ -203,16 +203,21 @@
     assert(config);
 
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+
     bool mdok;                          // Status of MD lookup
-    bool tempDelete = psMetadataLookupBool(&mdok, config->arguments, "TEMP.DELETE"); // Delete temporary files?
-    const char *tempImage = psMetadataLookupStr(NULL, config->arguments, "TEMP.IMAGE"); // Suffix for temporary images
-    const char *tempMask = psMetadataLookupStr(NULL, config->arguments, "TEMP.MASK"); // Suffix for temporary masks
-    const char *tempWeight = psMetadataLookupStr(NULL, config->arguments, "TEMP.WEIGHT"); // Suffix for temporary weight (variance) maps
+    bool tempDelete = psMetadataLookupBool(&mdok, recipe, "TEMP.DELETE"); // Delete temporary files?
+    const char *tempImage = psMetadataLookupStr(NULL, recipe, "TEMP.IMAGE"); // Suffix for temporary images
+    const char *tempMask = psMetadataLookupStr(NULL, recipe, "TEMP.MASK"); // Suffix for temporary masks
+    const char *tempWeight = psMetadataLookupStr(NULL, recipe, "TEMP.WEIGHT"); // Suffix for temp weight maps
     if (!tempImage || !tempMask || !tempWeight) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to find TEMP.IMAGE, TEMP.MASK and TEMP.WEIGHT");
-        return false;
-    }
-
-    float threshold = psMetadataLookupF32(NULL, config->arguments, "THRESHOLD.MASK"); // Threshold for mask deconvolution
-    float imageRej = psMetadataLookupF32(NULL, config->arguments, "IMAGE.REJ"); // Maximum fraction of image to reject before rejecting entire image
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Unable to find TEMP.IMAGE, TEMP.MASK and TEMP.WEIGHT in recipe");
+        return false;
+    }
+
+    float threshold = psMetadataLookupF32(NULL, recipe, "THRESHOLD.MASK"); // Threshold for mask deconvolution
+    float imageRej = psMetadataLookupF32(NULL, recipe, "IMAGE.REJ"); // Maximum fraction of image to reject
+                                                                     // before rejecting entire image
 
     const char *statsName = psMetadataLookupStr(&mdok, config->arguments, "STATS"); // Filename for statistics
@@ -238,7 +243,9 @@
     }
     int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs
-    int numScans = psMetadataLookupS32(NULL, config->arguments, "ROWS"); // Number of scans to read at once
+    int numScans = psMetadataLookupS32(NULL, recipe, "ROWS"); // Number of scans to read at once
+
     psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
-    int overlap = 2 * psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Overlap by kernel size between consecutive scans
+    int overlap = 2 * psMetadataLookupS32(NULL, ppsub,
+                                          "KERNEL.SIZE"); // Overlap by kernel size between consecutive scans
 
     if (!pmConfigMaskSetBits(NULL, NULL, config)) {
@@ -770,5 +777,5 @@
         memDump("final");
 
-        if (psMetadataLookupBool(&mdok, config->arguments, "PHOTOMETRY")) {
+        if (psMetadataLookupBool(&mdok, recipe, "PHOTOMETRY")) {
 
             fileActivation(config, combineFiles, false);
Index: /trunk/ppStack/src/ppStackMatch.c
===================================================================
--- /trunk/ppStack/src/ppStackMatch.c	(revision 18917)
+++ /trunk/ppStack/src/ppStackMatch.c	(revision 18918)
@@ -27,7 +27,10 @@
     pmReadout *output = pmReadoutAlloc(NULL); // Output readout, for holding results temporarily
 
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+
     // Look up appropriate values from the ppSub recipe
-    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
-    int size = psMetadataLookupS32(NULL, recipe, "KERNEL.SIZE"); // Kernel half-size
+    psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
+    int size = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size
 
     psMaskType maskIn = pmConfigMaskGet("MASK.VALUE", config); // Bits to mask going in to pmSubtractionMatch
@@ -35,12 +38,9 @@
 
     bool mdok;                          // Status of MD lookup
-    bool renorm = psMetadataLookupBool(&mdok, config->arguments, "RENORM"); // Renormalise variances?
-    psStatsOptions renormMean = psMetadataLookupS32(&mdok, config->arguments,
-                                                    "RENORM.MEAN"); // Statistic for mean
-    psStatsOptions renormStdev = psMetadataLookupS32(&mdok, config->arguments,
-                                                     "RENORM.STDEV"); // Statistic for stdev
-    int renormWidth = psMetadataLookupS32(&mdok, config->arguments,
-                                          "RENORM.WIDTH"); // Width for renormalisation box
-    float penalty = psMetadataLookupF32(NULL, config->arguments, "PENALTY"); // Penalty for wideness
+    bool renorm = psMetadataLookupBool(&mdok, recipe, "RENORM"); // Renormalise variances?
+    psStatsOptions renormMean = psMetadataLookupS32(&mdok, recipe, "RENORM.MEAN"); // Statistic for mean
+    psStatsOptions renormStdev = psMetadataLookupS32(&mdok, recipe, "RENORM.STDEV"); // Statistic for stdev
+    int renormWidth = psMetadataLookupS32(&mdok, recipe, "RENORM.WIDTH"); // Width for renormalisation box
+    float penalty = psMetadataLookupF32(NULL, ppsub, "PENALTY"); // Penalty for wideness
 
     if (!pmReadoutMaskNonfinite(readout, maskIn)) {
@@ -53,25 +53,25 @@
         assert(sources);
 
-        int order = psMetadataLookupS32(NULL, recipe, "SPATIAL.ORDER"); // Spatial polynomial order
-        float regionSize = psMetadataLookupF32(NULL, recipe, "REGION.SIZE"); // Size of iso-kernel regs
-        float spacing = psMetadataLookupF32(NULL, recipe, "STAMP.SPACING"); // Typical stamp spacing
-        int footprint = psMetadataLookupS32(NULL, recipe, "STAMP.FOOTPRINT"); // Stamp half-size
-        float threshold = psMetadataLookupF32(NULL, recipe, "STAMP.THRESHOLD"); // Threshold for stmps
-        int iter = psMetadataLookupS32(NULL, recipe, "ITER"); // Rejection iterations
-        float rej = psMetadataLookupF32(NULL, recipe, "REJ"); // Rejection threshold
+        int order = psMetadataLookupS32(NULL, ppsub, "SPATIAL.ORDER"); // Spatial polynomial order
+        float regionSize = psMetadataLookupF32(NULL, ppsub, "REGION.SIZE"); // Size of iso-kernel regs
+        float spacing = psMetadataLookupF32(NULL, ppsub, "STAMP.SPACING"); // Typical stamp spacing
+        int footprint = psMetadataLookupS32(NULL, ppsub, "STAMP.FOOTPRINT"); // Stamp half-size
+        float threshold = psMetadataLookupF32(NULL, ppsub, "STAMP.THRESHOLD"); // Threshold for stmps
+        int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations
+        float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold
         pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(
-            psMetadataLookupStr(NULL, recipe, "KERNEL.TYPE")); // Kernel type
-        psVector *widths = psMetadataLookupPtr(NULL, recipe, "ISIS.WIDTHS"); // ISIS Gaussian widths
-        psVector *orders = psMetadataLookupPtr(NULL, recipe, "ISIS.ORDERS"); // ISIS Polynomial orders
-        int inner = psMetadataLookupS32(NULL, recipe, "INNER"); // Inner radius
-        int ringsOrder = psMetadataLookupS32(NULL, recipe, "RINGS.ORDER"); // RINGS polynomial order
-        int binning = psMetadataLookupS32(NULL, recipe, "SPAM.BINNING"); // Binning for SPAM kernel
-        float badFrac = psMetadataLookupF32(NULL, recipe, "BADFRAC"); // Maximum bad fraction
-        bool optimum = psMetadataLookupBool(&mdok, recipe, "OPTIMUM"); // Derive optimum parameters?
-        float optMin = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.MIN"); // Minimum width for search
-        float optMax = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.MAX"); // Maximum width for search
-        float optStep = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.STEP"); // Step for search
-        float optThresh = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.TOL"); // Tolerance for search
-        int optOrder = psMetadataLookupS32(&mdok, recipe, "OPTIMUM.ORDER"); // Order for search
+            psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE")); // Kernel type
+        psVector *widths = psMetadataLookupPtr(NULL, ppsub, "ISIS.WIDTHS"); // ISIS Gaussian widths
+        psVector *orders = psMetadataLookupPtr(NULL, ppsub, "ISIS.ORDERS"); // ISIS Polynomial orders
+        int inner = psMetadataLookupS32(NULL, ppsub, "INNER"); // Inner radius
+        int ringsOrder = psMetadataLookupS32(NULL, ppsub, "RINGS.ORDER"); // RINGS polynomial order
+        int binning = psMetadataLookupS32(NULL, ppsub, "SPAM.BINNING"); // Binning for SPAM kernel
+        float badFrac = psMetadataLookupF32(NULL, ppsub, "BADFRAC"); // Maximum bad fraction
+        bool optimum = psMetadataLookupBool(&mdok, ppsub, "OPTIMUM"); // Derive optimum parameters?
+        float optMin = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.MIN"); // Minimum width for search
+        float optMax = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.MAX"); // Maximum width for search
+        float optStep = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.STEP"); // Step for search
+        float optThresh = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.TOL"); // Tolerance for search
+        int optOrder = psMetadataLookupS32(&mdok, ppsub, "OPTIMUM.ORDER"); // Order for search
 
         // These values are specified specifically for stacking
Index: /trunk/ppStack/src/ppStackPSF.c
===================================================================
--- /trunk/ppStack/src/ppStackPSF.c	(revision 18917)
+++ /trunk/ppStack/src/ppStackPSF.c	(revision 18918)
@@ -12,8 +12,11 @@
 {
     // Get the recipe values
-    int psfInstances = psMetadataLookupS32(NULL, config->arguments, "PSF.INSTANCES"); // Number of instances for PSF
-    float psfRadius = psMetadataLookupF32(NULL, config->arguments, "PSF.RADIUS"); // Radius for PSF
-    const char *psfModel = psMetadataLookupStr(NULL, config->arguments, "PSF.MODEL"); // Model for PSF
-    int psfOrder = psMetadataLookupS32(NULL, config->arguments, "PSF.ORDER"); // Spatial order for PSF
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+
+    int psfInstances = psMetadataLookupS32(NULL, recipe, "PSF.INSTANCES"); // Number of instances for PSF
+    float psfRadius = psMetadataLookupF32(NULL, recipe, "PSF.RADIUS"); // Radius for PSF
+    const char *psfModel = psMetadataLookupStr(NULL, recipe, "PSF.MODEL"); // Model for PSF
+    int psfOrder = psMetadataLookupS32(NULL, recipe, "PSF.ORDER"); // Spatial order for PSF
 
     // Solve for the target PSF
Index: /trunk/ppStack/src/ppStackReadout.c
===================================================================
--- /trunk/ppStack/src/ppStackReadout.c	(revision 18917)
+++ /trunk/ppStack/src/ppStackReadout.c	(revision 18918)
@@ -27,15 +27,17 @@
     static int sectionNum = 0;          // Section number; for debugging outputs
 
-
     // Get the recipe values
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+
     bool mdok;                          // Status of MD lookup
-    int iter = psMetadataLookupS32(NULL, config->arguments, "ITER"); // Rejection iterations
-    float combineRej = psMetadataLookupF32(NULL, config->arguments, "COMBINE.REJ"); // Combination threshold
+    int iter = psMetadataLookupS32(NULL, recipe, "ITER"); // Rejection iterations
+    float combineRej = psMetadataLookupF32(NULL, recipe, "COMBINE.REJ"); // Combination threshold
     psMaskType maskVal = pmConfigMaskGet("BLANK", config); // Value to mask
-    bool useVariance = psMetadataLookupBool(&mdok, config->arguments, "VARIANCE"); // Use variance for rejection?
-    bool safe = psMetadataLookupBool(&mdok, config->arguments, "SAFE"); // Play safe when combining small numbers of pixels?
+    bool useVariance = psMetadataLookupBool(&mdok, recipe, "VARIANCE"); // Use variance for rejection?
+    bool safe = psMetadataLookupBool(&mdok, recipe, "SAFE"); // Be safe when combining small numbers of pixels
+
     psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
     int kernelSize = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size
-
 
     int num = readouts->n;              // Number of inputs
@@ -137,7 +139,10 @@
 
     // Get the recipe values
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+
     bool mdok;                          // Status of MD lookup
     psMaskType maskVal = pmConfigMaskGet("BLANK", config); // Value to mask
-    bool useVariance = psMetadataLookupBool(&mdok, config->arguments, "VARIANCE"); // Use variance for rejection?
+    bool useVariance = psMetadataLookupBool(&mdok, recipe, "VARIANCE"); // Use variance for rejection?
 
     int num = readouts->n;              // Number of inputs
Index: /trunk/ppStack/src/ppStackSources.c
===================================================================
--- /trunk/ppStack/src/ppStackSources.c	(revision 18917)
+++ /trunk/ppStack/src/ppStackSources.c	(revision 18918)
@@ -330,8 +330,10 @@
 
     // Read recipe values
-    float radius = psMetadataLookupF32(NULL, config->arguments, "SOURCE.RADIUS"); // Exclusion radius
-    int minOverlap = psMetadataLookupS32(NULL, config->arguments, "SOURCE.MIN"); // Minimum number
-    int iter = psMetadataLookupS32(NULL, config->arguments, "SOURCE.ITER"); // Clipping iterations
-    float rej = psMetadataLookupF32(NULL, config->arguments, "SOURCE.REJ"); // Clipping rejection
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+    float radius = psMetadataLookupF32(NULL, recipe, "SOURCE.RADIUS"); // Exclusion radius
+    int minOverlap = psMetadataLookupS32(NULL, recipe, "SOURCE.MIN"); // Minimum number
+    int iter = psMetadataLookupS32(NULL, recipe, "SOURCE.ITER"); // Clipping iterations
+    float rej = psMetadataLookupF32(NULL, recipe, "SOURCE.REJ"); // Clipping rejection
 
     // Look for overlaps with existing lists
@@ -370,5 +372,7 @@
     PS_ASSERT_PTR_NON_NULL(config, NULL);
 
-    float radius = psMetadataLookupF32(NULL, config->arguments, "SOURCE.RADIUS"); // Exclusion radius
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+    float radius = psMetadataLookupF32(NULL, recipe, "SOURCE.RADIUS"); // Exclusion radius
 
     int numLists = 0;                   // Number of lists
