Index: trunk/ppSub/src/ppSubReadoutPhotometry.c
===================================================================
--- trunk/ppSub/src/ppSubReadoutPhotometry.c	(revision 23688)
+++ trunk/ppSub/src/ppSubReadoutPhotometry.c	(revision 23740)
@@ -22,8 +22,11 @@
 #include "ppSub.h"
 
-bool ppSubReadoutPhotometry (pmConfig *config, ppSubData *data, const pmFPAview *view)
+bool ppSubReadoutPhotometry(const char *name, pmConfig *config, ppSubData *data)
 {
     psAssert(config, "Require configuration");
-    psAssert(view, "Require view");
+
+    if (!data->photometry) {
+        return false;
+    }
 
     // Look up recipe values
@@ -39,4 +42,5 @@
     // The PSF (measured in ppSubMakePSF) is stored on the chip->analysis of PSPHOT.INPUT
     // In order to use an incoming PSF, it must be stored on the chip->analysis of PSPHOT.PSF.LOAD
+    pmFPAview *view = ppSubViewReadout(); // View to readout
     pmChip *psfInputChip = pmFPAfileThisChip(config->files, view, "PSPHOT.INPUT"); // Chip with PSF
     psAssert (psfInputChip, "should have been generated for ppSubMakePSF");
@@ -47,5 +51,5 @@
         psErrorStackPrint(stderr, "No PSF available");
         psWarning("No PSF available --- suspect bad data quality.");
-        ppSubDataQuality(config, data, psErrorCodeLast(), PPSUB_FILES_PHOT);
+        ppSubDataQuality(config, data, psErrorCodeLast(), PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV);
         return true;
     }
@@ -58,8 +62,6 @@
     // around the pointers so PSPHOT.INPUT corresponds to the output image; previously, it was
     // equivalent to the minuend image.
-    pmFPAfile *outputFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.OUTPUT"); // Output file
-    pmReadout *outRO = pmFPAviewThisReadout(view, outputFile->fpa); // Readout with the sources
+    pmReadout *inRO = pmFPAfileThisReadout(config->files, view, name); // Readout with image and sources
 
-    // XXX possibly rename this to PPSUB.RESID?
     pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.INPUT"); // Photometry file
     pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer
@@ -68,17 +70,22 @@
         photRO = pmReadoutAlloc(cell); // Output readout: subtraction
     }
-    photRO->image = psImageCopy(photRO->image, outRO->image, PS_TYPE_F32);
-    if (outRO->variance) {
-        photRO->variance = psImageCopy(photRO->variance, outRO->variance, PS_TYPE_F32);
+    photRO->image = psImageCopy(photRO->image, inRO->image, PS_TYPE_F32);
+    if (inRO->variance) {
+        photRO->variance = psImageCopy(photRO->variance, inRO->variance, PS_TYPE_F32);
     } else {
         psFree(photRO->variance);
         photRO->variance = NULL;
     }
-    if (outRO->mask) {
-        photRO->mask = psImageCopy(photRO->mask, outRO->mask, PS_TYPE_IMAGE_MASK);
+    if (inRO->mask) {
+        photRO->mask = psImageCopy(photRO->mask, inRO->mask, PS_TYPE_IMAGE_MASK);
     } else {
         psFree(photRO->mask);
         photRO->mask = NULL;
     }
+    psMetadataAddPtr(photRO->parent->parent->analysis, PS_LIST_TAIL, "PSPHOT.PSF",
+                     PS_META_REPLACE | PS_DATA_UNKNOWN, "Point-spread function", data->psf);
+
+    psFree(photRO->analysis);
+    photRO->analysis = psMetadataAlloc();
 
     if (!psphotReadoutMinimal(config, view)) {
@@ -87,17 +94,23 @@
         psErrorStackPrint(stderr, "Unable to perform photometry on image");
         psWarning("Unable to perform photometry on image --- suspect bad data quality.");
-        ppSubDataQuality(config, data, psErrorCodeLast(), PPSUB_FILES_PHOT);
+        ppSubDataQuality(config, data, psErrorCodeLast(), PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV);
     }
 
-    photRO->data_exists = true;
-    photRO->parent->data_exists = true;
-    photRO->parent->parent->data_exists = true;
+    if (!data->quality && !psMetadataCopySingle(inRO->analysis, photRO->analysis, "PSPHOT.SOURCES")) {
+        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to copy PSPHOT.SOURCES");
+        return false;
+    }
 
     if (data->stats) {
         psArray *sources = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.SOURCES"); // Sources
-        psMetadataAddS32(data->stats, PS_LIST_TAIL, "NUM_SOURCES", 0, "Number of sources detected",
-                         sources ? sources->n : 0);
-        psMetadataAddF32(data->stats, PS_LIST_TAIL, "TIME_PHOT", 0, "Time to do photometry",
-                         psTimerClear("PPSUB_PHOT"));
+        bool mdok;
+        int numSources = psMetadataLookupS32(&mdok, data->stats, "NUM_SOURCES"); // Number of sources
+        numSources += sources ? sources->n : 0;
+        psMetadataAddS32(data->stats, PS_LIST_TAIL, "NUM_SOURCES", PS_META_REPLACE,
+                         "Total number of sources detected", numSources);
+        float newTime = psTimerClear("PPSUB_PHOT"); // Time for photometry
+        float oldTime = psMetadataLookupF32(&mdok, data->stats, "TIME_PHOT"); // Previous time for photometry
+        psMetadataAddF32(data->stats, PS_LIST_TAIL, "TIME_PHOT", PS_META_REPLACE, "Time to do photometry",
+                         isfinite(oldTime) ? oldTime + newTime : newTime);
     }
 
