Index: trunk/psphot/src/psphotMergeSources.c
===================================================================
--- trunk/psphot/src/psphotMergeSources.c	(revision 28013)
+++ trunk/psphot/src/psphotMergeSources.c	(revision 29936)
@@ -8,8 +8,5 @@
 bool psphotMergeSources (pmConfig *config, const pmFPAview *view, const char *filerule)
 {
-    bool status = true;
-
-    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
@@ -70,5 +67,5 @@
 // XXX This function needs to be updated to loop over set of input files.  At the moment, we
 // only expect a single entry for PSPHOT.INPUT.CMF and PSPHOT.SOURCES.TEXT, so we can only
-// associate input sources with a single entry for PSPHOT.INPUT
+// associate input sources with a single entry for the filerule
 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view, const char *filerule) {
 
@@ -166,4 +163,69 @@
 }
 
+// copy the known sources (as external) to the detection list of the given filerule
+bool psphotAddKnownSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *inSources) {
+
+    bool status = false;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    // determine properties (sky, moments) of initial sources
+    float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
+    psAssert (status, "missing SKY_OUTER_RADIUS in recipe?");
+
+    // XXX this seems like an arbitrary number...
+    OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius
+
+    // find the currently selected readout 
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, 0); // File of interest
+    psAssert (file, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    if (!detections) {
+	detections = pmDetectionsAlloc();
+	detections->newSources = psArrayAllocEmpty (100);
+	// save detections on the readout->analysis
+	if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detections", detections)) {
+	    psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
+	    return false;
+	}
+    } else {
+	psMemIncrRefCounter(detections); // so we can free the detections below
+    }
+
+    // copy the sources from inSources to the new detection structure
+    for (int i = 0; i < inSources->n; i++) {
+      pmSource *inSource = inSources->data[i];
+
+      pmSource *newSource = pmSourceCopy(inSource);
+      newSource->mode |= PM_SOURCE_MODE_EXTERNAL;
+      
+      // drop the loaded source modelPSF
+      psFree (newSource->modelPSF);
+      // source->modelPSF = NULL;  check this!
+
+      // drop the references to the original image pixels:
+      pmSourceFreePixels (newSource);
+
+      // allocate image, weight, mask for the new image for each peak (square of radius OUTER)
+      pmSourceDefinePixels (newSource, readout, newSource->peak->x, newSource->peak->y, OUTER);
+
+      newSource->imageID = 0;
+      // XXX reset the source ID? raised questions about the meaning of this ID...
+      // P_PM_SOURCE_SET_ID(source, i);
+
+      psArrayAdd (detections->newSources, 100, newSource);
+    }
+    psLogMsg ("psphot", 3, "%ld known sources supplied", detections->newSources->n);
+
+    psFree (detections);
+    return true;
+}
+
 // extract the input sources corresponding to this readout
 // XXX this function needs to be updated to work with the new context of psphot inputs
@@ -405,6 +467,5 @@
     bool status = true;
 
-    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
-    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
+    int num = psphotFileruleCount(config, ruleSrc);
 
     // skip the chisq image because it is a duplicate of the detection version
