Index: trunk/psphot/src/psphotOutput.c
===================================================================
--- trunk/psphot/src/psphotOutput.c	(revision 29902)
+++ trunk/psphot/src/psphotOutput.c	(revision 29936)
@@ -1,3 +1,19 @@
 # include "psphotInternal.h"
+
+// convert filerule to filerule.NUM and look up in the config->arguments metadata
+int psphotFileruleCount(const pmConfig *config, const char *filerule) {
+
+    bool status = false;
+
+    psString name = NULL;
+    psStringAppend(&name, "%s.NUM", filerule);
+    int num = psMetadataLookupS32 (&status, config->arguments, name);
+    if (!status) {
+      // we only explicitly define (filerule.NUM) if we have more than 1
+      num = 1;
+    }
+    psFree (name);
+    return num;
+}
 
 pmReadout *psphotSelectBackground (pmConfig *config,
@@ -63,15 +79,4 @@
     fclose (f);
     return true;
-}
-
-// XXX replace this with a call to a pmConfig function (pmConfigDump...)
-bool psphotDumpConfig (pmConfig *config) {
-
-  psMetadataConfigWrite (config->user, "user.md");
-  psMetadataConfigWrite (config->camera, "camera.md");
-  psMetadataConfigWrite (config->recipes, "recipes.md");
-  psMetadataConfigWrite (config->arguments, "arguments.md");
-  psMetadataConfigWrite (config->files, "files.md");
-  return true;
 }
 
@@ -126,15 +131,42 @@
 }
 
+bool psphotCleanInputsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index);
+bool psphotCleanInputs (pmConfig *config, const pmFPAview *view, const char *filerule) {
+
+    int num = psphotFileruleCount(config, filerule);
+
+    // loop over the available readouts
+    for (int i = 0; i < num; i++) {
+	if (!psphotCleanInputsReadout (config, view, filerule, i)) {
+	  psError (PSPHOT_ERR_CONFIG, false, "failed to clean inputs for %s entry %d", filerule, i);
+	    return false;
+	}
+    }
+    return true;
+}
+
+bool psphotCleanInputsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index) {
+
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, index); // File of interest
+    PS_ASSERT (file, false);
+
+    pmReadout  *readout = pmFPAviewThisReadout (view, file->fpa);
+
+    // XXX anything else to remove?
+    if (psMetadataLookup(readout->analysis, "PSPHOT.DETECTIONS")) {
+	psMetadataRemoveKey(readout->analysis, "PSPHOT.DETECTIONS");
+    }
+
+    return true;
+}
+
 bool psphotAddPhotcode (pmConfig *config, const pmFPAview *view, const char *filerule) {
 
-    bool status = false;
-
-    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
-    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
+    int num = psphotFileruleCount(config, filerule);
 
     // loop over the available readouts
     for (int i = 0; i < num; i++) {
 	if (!psphotAddPhotcodeReadout (config, view, filerule, i)) {
-            psError (PSPHOT_ERR_CONFIG, false, "failed to add photcode to PSPHOT.INPUT entry %d", i);
+	  psError (PSPHOT_ERR_CONFIG, false, "failed to add photcode to %s entry %d", filerule, i);
 	    return false;
 	}
@@ -357,5 +389,5 @@
     // XXX need alternative output function
     // psMetadata *psfData = pmPSFtoMetadata (NULL, try->psf);
-    // psMetadataConfigWrite (psfData, "psfmodel.dat");
+    // psMetadataConfigWrite (psfData, "psfmodel.dat", NULL);
     psLogMsg ("psphot.choosePSF", PS_LOG_INFO, "wrote out psf-subtracted image, psf data, exiting\n");
 
