Index: trunk/psphot/src/psphot.h
===================================================================
--- trunk/psphot/src/psphot.h	(revision 37930)
+++ trunk/psphot/src/psphot.h	(revision 37932)
@@ -45,4 +45,6 @@
 bool            psphotReadoutCleanup (pmConfig *config, const pmFPAview *view, const char *filerule);
 bool            psphotReadoutCleanupReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
+bool            psphotReadoutCleanupMinimal (pmConfig *config, const pmFPAview *view, const char *filerule);
+bool            psphotReadoutCleanupReadoutMinimal (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe);
 
 bool            psphotDefineFiles (pmConfig *config, pmFPAfile *input);
Index: trunk/psphot/src/psphotReadoutCleanup.c
===================================================================
--- trunk/psphot/src/psphotReadoutCleanup.c	(revision 37930)
+++ trunk/psphot/src/psphotReadoutCleanup.c	(revision 37932)
@@ -111,2 +111,87 @@
     return true;
 }
+
+// for now, let's store the detections on the readout->analysis for each readout
+bool psphotReadoutCleanupMinimal (pmConfig *config, const pmFPAview *view, const char *filerule)
+{
+    bool status = true;
+
+    // remove internal pmFPAfiles, if created
+    if (psErrorCodeLast() == (psErrorCode) PSPHOT_ERR_DATA) {
+        psErrorStackPrint(stderr, "Error in the psphot readout analysis");
+        psErrorClear();
+    }
+    if (psErrorCodeLast() != PS_ERR_NONE) {
+        return false;
+    }
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    int num = psphotFileruleCount(config, filerule);
+
+    // loop over the available readouts
+    for (int i = 0; i < num; i++) {
+	if (!psphotReadoutCleanupReadoutMinimal (config, view, filerule, i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on psphotReadoutCleanupMinimal for %s entry %d", filerule, i);
+	    return false;
+	}
+    }
+
+    // XXX move this to top of loop?
+    pmKapaClose ();
+
+    return true;
+}
+
+// psphotReadoutCleanupMinimal is called on exit from psphotReadoutMinimal.  If the last raised error is
+// not a DATA error, then there was a serious problem.  Only in this case, or if the fail
+// on the stats measurement, do we return false
+bool psphotReadoutCleanupReadoutMinimal (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe) {
+
+    bool status = true;
+
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, index); // File of interest
+    psAssert (file, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    // when psphotReadoutCleanupMinimal is called, these are not necessarily defined
+    pmPSF        *psf        = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psArray      *sources    = detections ? detections->allSources : NULL;
+    // XXX where do we free these, in here (psMetadataRemove?)
+
+    // create an output header with stats results currently saved on readout->analysis
+    psMetadata *header = psphotDefineHeader (readout->analysis);
+
+    // write NSTARS to the image header
+    psphotSetHeaderNstars (header, sources);
+
+    // save the results of the analysis
+    // this should happen way up stream (when needed?)
+    psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.HEADER",  PS_DATA_METADATA | PS_META_REPLACE, "header stats", header);
+
+    if (psf) {
+	// XXX this seems a little silly : we saved the psf on readout->analysis above, but now
+	// we are moving it to chip->analysis.
+        // save the psf for possible output.  if there was already an entry, it was loaded from external sources
+        // the new one may have been updated or modified, so replace the existing entry.  We
+        // are required to save it on the chip, but this will cause problems if we ever want to
+        // run psphot on an unmosaiced image
+        pmCell *cell = readout->parent;
+        pmChip *chip = cell->parent;
+        psMetadataAdd (chip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE,  "psphot psf", psf);
+    }
+
+    if (psErrorCodeLast() != PS_ERR_NONE) {
+        psErrorStackPrint(stderr, "unexpected remaining errors");
+        abort();
+    }
+
+    psFree (header);
+    return true;
+}
Index: trunk/psphot/src/psphotReadoutMinimal.c
===================================================================
--- trunk/psphot/src/psphotReadoutMinimal.c	(revision 37930)
+++ trunk/psphot/src/psphotReadoutMinimal.c	(revision 37932)
@@ -112,4 +112,4 @@
 
     // create the exported-metadata and free local data
-    return psphotReadoutCleanup (config, view, filerule);
+    return psphotReadoutCleanupMinimal (config, view, filerule);
 }
