Index: trunk/ppSub/src/ppSubCamera.c
===================================================================
--- trunk/ppSub/src/ppSubCamera.c	(revision 26571)
+++ trunk/ppSub/src/ppSubCamera.c	(revision 26899)
@@ -23,5 +23,6 @@
 
 // Define an input file
-static pmFPAfile *defineInputFile(pmConfig *config,// Configuration
+static pmFPAfile *defineInputFile(bool *success,
+                                  pmConfig *config,// Configuration
                                   pmFPAfile *bind,    // File to which to bind, or NULL
                                   char *filerule,     // Name of file rule
@@ -32,5 +33,8 @@
     bool status;
 
+    *success = false;
+
     pmFPAfile *file = NULL;
+
     // look for the file on the argument list
     if (bind) {
@@ -39,4 +43,5 @@
         file = pmFPAfileDefineFromArgs(&status, config, filerule, argname);
     }
+
     if (!status) {
         psError(PS_ERR_UNKNOWN, false, "Failed to load file definition for %s", filerule);
@@ -53,4 +58,6 @@
 
     if (!file) {
+        // no file defined
+        *success = true;
         return NULL;
     }
@@ -61,4 +68,5 @@
     }
 
+    *success = true;
     return file;
 }
@@ -137,4 +145,6 @@
 bool ppSubCamera(ppSubData *data)
 {
+    bool success = true;
+
     psAssert(data, "Require processing data");
     pmConfig *config = data->config;
@@ -142,25 +152,52 @@
 
     // Input image
-    pmFPAfile *input = defineInputFile(config, NULL, "PPSUB.INPUT", "INPUT", PM_FPA_FILE_IMAGE);
-    if (!input) {
+    pmFPAfile *input = defineInputFile(&success, config, NULL, "PPSUB.INPUT", "INPUT", PM_FPA_FILE_IMAGE);
+    if (!success) {
         psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT");
         return false;
     }
-    defineInputFile(config, input, "PPSUB.INPUT.MASK", "INPUT.MASK", PM_FPA_FILE_MASK);
-    pmFPAfile *inVar = defineInputFile(config, input, "PPSUB.INPUT.VARIANCE", "INPUT.VARIANCE",
-                                       PM_FPA_FILE_VARIANCE);
-    defineInputFile(config, NULL, "PPSUB.INPUT.SOURCES", "INPUT.SOURCES", PM_FPA_FILE_CMF);
+
+    defineInputFile(&success, config, input, "PPSUB.INPUT.MASK", "INPUT.MASK", PM_FPA_FILE_MASK);
+    if (!success) {
+        psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT.MASK");
+        return false;
+    }
+
+    pmFPAfile *inVar = defineInputFile(&success, config, input, "PPSUB.INPUT.VARIANCE", "INPUT.VARIANCE", PM_FPA_FILE_VARIANCE);
+    if (!success) {
+        psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT.VARIANCE");
+        return false;
+    }
+
+    defineInputFile(&success, config, NULL, "PPSUB.INPUT.SOURCES", "INPUT.SOURCES", PM_FPA_FILE_CMF);
+    if (!success) {
+        psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT.SOURCES");
+        return false;
+    }
 
     // Reference image
-    pmFPAfile *ref = defineInputFile(config, NULL, "PPSUB.REF", "REF", PM_FPA_FILE_IMAGE);
-    if (!ref) {
+    pmFPAfile *ref = defineInputFile(&success, config, NULL, "PPSUB.REF", "REF", PM_FPA_FILE_IMAGE);
+    if (!success) {
         psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF");
         return false;
     }
-    defineInputFile(config, ref, "PPSUB.REF.MASK", "REF.MASK", PM_FPA_FILE_MASK);
-    pmFPAfile *refVar = defineInputFile(config, ref, "PPSUB.REF.VARIANCE", "REF.VARIANCE",
-                                        PM_FPA_FILE_VARIANCE);
-    defineInputFile(config, NULL, "PPSUB.REF.SOURCES", "REF.SOURCES", PM_FPA_FILE_CMF);
-
+
+    defineInputFile(&success, config, ref, "PPSUB.REF.MASK", "REF.MASK", PM_FPA_FILE_MASK);
+    if (!success) {
+        psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF.MASK");
+        return false;
+    }
+
+    pmFPAfile *refVar = defineInputFile(&success, config, ref, "PPSUB.REF.VARIANCE", "REF.VARIANCE", PM_FPA_FILE_VARIANCE);
+    if (!success) {
+        psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF.VARIANCE");
+        return false;
+    }
+
+    defineInputFile(&success, config, NULL, "PPSUB.REF.SOURCES", "REF.SOURCES", PM_FPA_FILE_CMF);
+    if (!success) {
+        psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF.SOURCES");
+        return false;
+    }
 
     // Now that the camera has been determined, we can read the recipe
@@ -298,4 +335,16 @@
     jpeg2->save = true;
 
+    // Output residual JPEG
+    pmFPAfile *jpeg3 = pmFPAfileDefineOutput(config, NULL, "PPSUB.OUTPUT.RESID.JPEG");
+    if (!jpeg3) {
+        psError(PS_ERR_IO, false, _("Unable to generate output file from PPSUB.OUTPUT.RESID.JPEG"));
+        return false;
+    }
+    if (jpeg3->type != PM_FPA_FILE_JPEG) {
+        psError(PS_ERR_IO, true, "PPSUB.OUTPUT.RESID.JPEG is not of type JPEG");
+        return false;
+    }
+    jpeg3->save = true;
+
     // Output subtraction kernel
     pmFPAfile *kernel = defineCalcFile(config, NULL, "PPSUB.OUTPUT.KERNELS", PM_FPA_FILE_SUBKERNEL);
@@ -306,5 +355,5 @@
 
     // psPhot input
-    if (data->photometry) {
+    if (data->photometry || 1) {
         psphotModelClassInit();        // load implementation-specific models
 
@@ -318,8 +367,10 @@
             return false;
         }
+        // specify the number of psphot input images
+        psMetadataAddS32 (config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "number of inputs", 1);
         pmFPAfileActivate(config->files, false, "PSPHOT.INPUT");
 
-        // Internal-ish file for getting the PSF from the minuend
-        pmFPAfile *psf = pmFPAfileDefineOutputFromFile(config, psphot, "PSPHOT.PSF.LOAD");
+        // Internal file for getting the PSF from the minuend
+        pmFPAfile *psf = pmFPAfileDefineFromFPA(config, output->fpa, 1, 1, "PSPHOT.PSF.LOAD");
         if (!psf) {
             psError(PS_ERR_IO, false, "Failed to build FPA from PSPHOT.PSF.LOAD");
