Index: trunk/psphot/src/psphotMergeSources.c
===================================================================
--- trunk/psphot/src/psphotMergeSources.c	(revision 29936)
+++ trunk/psphot/src/psphotMergeSources.c	(revision 30624)
@@ -513,5 +513,236 @@
     }
 
-    return true;
-}
-
+    // loop over the sources, redefine their pixels to point at the new filerule image,
+    // copy the source data, and add a reference back to the original source
+    
+
+    return true;
+}
+
+// create source children from ruleSrc for ruleOut
+bool psphotSourceChildren (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc)
+{
+    bool status = true;
+
+    int num = psphotFileruleCount(config, ruleSrc);
+
+    // skip the chisq image because it is a duplicate of the detection version
+    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
+    if (!status) chisqNum = -1;
+
+    // loop over the available readouts
+    for (int i = 0; i < num; i++) {
+	if (i == chisqNum) continue; // skip chisq image
+        if (!psphotSourceChildrenReadout (config, view, ruleOut, ruleSrc, i)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed to copy sources from %s to %s entry %d", ruleSrc, ruleOut, i);
+            return false;
+        }
+    }
+    return true;
+}
+
+// create source children from ruleSrc for ruleOut for this entry.  XXX currently, this is only
+// used by psphotStackReadout (sources go on allSources so that psphotChoosePSF can be called
+// repeatedly)
+bool psphotSourceChildrenReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index) {
+
+    bool status;
+
+    // find the currently selected readout
+    pmFPAfile *fileSrc = pmFPAfileSelectSingle(config->files, ruleSrc, index); // File of interest
+    psAssert (fileSrc, "missing file?");
+
+    pmReadout *readoutSrc = pmFPAviewThisReadout(view, fileSrc->fpa);
+    psAssert (readoutSrc, "missing readout?");
+
+    pmDetections *detectionsSrc = psMetadataLookupPtr (&status, readoutSrc->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detectionsSrc, "missing detections?");
+
+    psArray *sourcesSrc = detectionsSrc->allSources;
+    psAssert (sourcesSrc, "missing sources?");
+
+    // find the currently selected readout
+    pmFPAfile *fileOut = pmFPAfileSelectSingle(config->files, ruleOut, index); // File of interest
+    psAssert (fileOut, "missing file?");
+
+    pmReadout *readoutOut = pmFPAviewThisReadout(view, fileOut->fpa);
+    psAssert (readoutOut, "missing readout?");
+
+    // generate a new detection structure for the output filerule
+    pmDetections *detectionsOut = psMetadataLookupPtr (&status, readoutOut->analysis, "PSPHOT.DETECTIONS");
+    if (!detectionsOut) {
+	detectionsOut = pmDetectionsAlloc();
+	detectionsOut->allSources = psArrayAllocEmpty (100);
+	// save detections on the readout->analysis
+	if (!psMetadataAddPtr (readoutOut->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detections", detectionsOut)) {
+	    psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
+	    return false;
+	}
+	psFree(detectionsOut); // a copy remains on the analysis metadata
+    }
+
+    // loop over the sources, redefine their pixels to point at the new filerule image,
+    // copy the source data, and add a reference back to the original source
+    
+    // copy the sources from sourceSrcs to the new detection structure
+    for (int i = 0; i < sourcesSrc->n; i++) {
+      pmSource *sourceSrc = sourcesSrc->data[i];
+
+      pmSource *sourceOut = pmSourceCopy(sourceSrc);
+      sourceOut->parent = sourceSrc;
+      
+      // keep the original source flags
+      sourceOut->type     = sourceSrc->type;
+      sourceOut->mode     = sourceSrc->mode;
+      sourceOut->mode2    = sourceSrc->mode2;
+      sourceOut->tmpFlags = sourceSrc->tmpFlags;
+
+      // does this copy all model data? (NO)
+      sourceOut->modelPSF = pmModelCopy(sourceSrc->modelPSF);
+      sourceOut->modelEXT = pmModelCopy(sourceSrc->modelEXT);
+
+      if (sourceSrc->modelFits) {
+	  sourceOut->modelFits = psArrayAlloc(sourceSrc->modelFits->n);
+	  for (int j = 0; j < sourceSrc->modelFits->n; j++) {
+	      sourceOut->modelFits->data[j] = pmModelCopy(sourceSrc->modelFits->data[j]);
+	  }
+      }
+
+      // drop the references to the original image pixels:
+      pmSourceFreePixels (sourceOut);
+
+      // allocate image, weight, mask for the new image for each peak
+      pmSourceRedefinePixels (sourceOut, readoutOut, sourceOut->peak->x, sourceOut->peak->y, sourceOut->modelPSF->fitRadius);
+
+      // child sources have not been subtracted in this image, but this flag may be raised if
+      // they were subtracted in the parent's image
+      sourceOut->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
+
+      psArrayAdd (detectionsOut->allSources, 100, sourceOut);
+      psFree (sourceOut);
+    }
+    psLogMsg ("psphot", 3, "%ld known sources supplied", detectionsOut->allSources->n);
+
+
+    return true;
+}
+
+// create source children associated with 'filerule' from the objectsSrc.  XXX currently, this
+// is only used by psphotStackReadout (sources go on allSources so that psphotChoosePSF can be
+// called repeatedly)
+psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc) {
+
+    bool status;
+
+    int nImages = psphotFileruleCount(config, filerule);
+
+    // generate look-up arrays for detections and readouts
+    psArray *detArrays = psArrayAlloc(nImages);
+    psArray *readouts = psArrayAlloc(nImages);
+
+    for (int i = 0; i < nImages; i++) {
+
+	// find the currently selected readout
+	pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, i); // 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->allSources = psArrayAllocEmpty (100);
+	    detections->peaks = 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 NULL;
+	    }
+	    psFree(detections); // a copy remains on the analysis metadata
+	    psAssert (detections, "missing detections?");
+	}
+	detArrays->data[i] = psMemIncrRefCounter(detections);
+	readouts->data[i] = psMemIncrRefCounter(readout);
+    }
+
+    psArray *objectsOut = psArrayAlloc(objectsSrc->n);
+
+    // copy all sources for each object
+    for (int k = 0; k < objectsSrc->n; k++) {
+
+        pmPhotObj *objectSrc = objectsSrc->data[k];
+	if (!objectSrc) continue;
+	if (!objectSrc->sources) continue;
+
+	pmPhotObj *objectOut = pmPhotObjAlloc();
+	objectsOut->data[k] = objectOut;
+
+	objectOut->SN = objectSrc->SN;
+	objectOut->x  = objectSrc->x;
+	objectOut->y  = objectSrc->y;
+	
+	objectOut->sources = psArrayAlloc(objectSrc->sources->n);
+
+	// copy the sources from sourceSrcs to the new detection structure
+	// loop over the sources, redefine their pixels to point at the new filerule image,
+	// copy the source data, and add a reference back to the original source
+	for (int i = 0; i < objectSrc->sources->n; i++) {
+
+	    pmSource *sourceSrc = objectSrc->sources->data[i];
+
+	    pmSource *sourceOut = pmSourceCopy(sourceSrc);
+	    objectOut->sources->data[i] = sourceOut;
+
+	    sourceOut->parent = sourceSrc;
+
+	    // keep the original source flags
+	    sourceOut->type     = sourceSrc->type;
+	    sourceOut->mode     = sourceSrc->mode;
+	    sourceOut->mode2    = sourceSrc->mode2;
+	    sourceOut->tmpFlags = sourceSrc->tmpFlags;
+
+	    // does this copy all model data? (NO)
+	    sourceOut->modelPSF = pmModelCopy(sourceSrc->modelPSF);
+	    sourceOut->modelEXT = pmModelCopy(sourceSrc->modelEXT);
+
+	    if (sourceSrc->modelFits) {
+		sourceOut->modelFits = psArrayAlloc(sourceSrc->modelFits->n);
+		for (int j = 0; j < sourceSrc->modelFits->n; j++) {
+		    sourceOut->modelFits->data[j] = pmModelCopy(sourceSrc->modelFits->data[j]);
+		}
+	    }
+
+	    // drop the references to the original image pixels:
+	    pmSourceFreePixels (sourceOut);
+
+	    // set the output readotu
+	    int index = sourceOut->imageID;
+	    if (index >= readouts->n) continue; // skip the sources generated by the chisq image
+	    pmReadout *readout = readouts->data[index];
+
+	    // allocate image, weight, mask for the new image for each peak
+	    pmSourceRedefinePixels (sourceOut, readout, sourceOut->peak->x, sourceOut->peak->y, sourceOut->modelPSF->fitRadius);
+
+	    // child sources have not been subtracted in this image, but this flag may be raised if
+	    // they were subtracted in the parent's image
+	    sourceOut->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
+
+	    // set the output detections:
+	    pmDetections *detectionsOut = detArrays->data[index];
+	    psArrayAdd (detectionsOut->allSources, 100, sourceOut);
+	    psArrayAdd (detectionsOut->peaks, 100, sourceOut->peak);
+	}
+    }
+
+    for (int i = 0; i < nImages; i++) {
+	pmDetections *detections = detArrays->data[i];
+	psLogMsg ("psphot", 3, "%ld source children for image %d", detections->allSources->n, i);
+    }
+
+    psFree (detArrays);
+    psFree (readouts);
+
+    return objectsOut;
+}
+
