Index: /branches/eam_branches/ipp-20101205/psModules/src/objects/pmSource.c
===================================================================
--- /branches/eam_branches/ipp-20101205/psModules/src/objects/pmSource.c	(revision 30141)
+++ /branches/eam_branches/ipp-20101205/psModules/src/objects/pmSource.c	(revision 30142)
@@ -127,4 +127,5 @@
     source->diffStats = NULL;
     source->radialAper = NULL;
+    source->parent = NULL;
 
     source->region = psRegionSet(NAN, NAN, NAN, NAN);
Index: /branches/eam_branches/ipp-20101205/psModules/src/objects/pmSource.h
===================================================================
--- /branches/eam_branches/ipp-20101205/psModules/src/objects/pmSource.h	(revision 30141)
+++ /branches/eam_branches/ipp-20101205/psModules/src/objects/pmSource.h	(revision 30142)
@@ -54,9 +54,9 @@
     pmPeak  *peak;                      ///< Description of peak pixel.
     psImage *pixels;                    ///< Rectangular region including object pixels.
-    psImage *variance;                    ///< Image variance.
+    psImage *variance;			///< Image variance.
     psImage *maskObj;                   ///< unique mask for this object which marks included pixels associated with objects.
     psImage *maskView;                  ///< view into global image mask for this object region
     psImage *modelFlux;                 ///< cached copy of the best model for this source
-    psImage *psfImage;                   ///< cached copy of the psf model for this source
+    psImage *psfImage;			///< cached copy of the psf model for this source
     pmMoments *moments;                 ///< Basic moments measured for the object.
     pmModel *modelPSF;                  ///< PSF Model fit (parameters and type)
@@ -90,6 +90,20 @@
     pmSourceDiffStats *diffStats;       ///< extra parameters for difference detections
     psArray *radialAper;		///< radial flux in circular apertures
+    pmSource *parent;			///< reference to the master source from which this is derived
     int imageID;
 };
+
+/* a pmSource is the information about a (possible) blob of flux in a specific image.  A source
+ * may represent an insignificant or undetected source.  There may be multiple representations
+ * of an image (eg, alternate smoothed copies); sources on alternate images may have a pointer
+ * to the version on the primary image (source->parent).  A set of sources on different, but
+ * related images (eg, multiple exposures or different filters) which (may) represent the same
+ * astronomical object are grouped together with the pmPhotObj type (set pmPhotObj.h).
+ * 
+ * A single source may be fitted with multiple models (not at the same time!).  The PSF model
+ * fit is a fit of the position (optionally) and the flux to the PSF model at the location of
+ * the source.  Alternate model fits are extended source models. The best model fit is used to
+ * subtract the object from the image.
+ */
 
 /** pmPSFClump data structure
Index: /branches/eam_branches/ipp-20101205/psphot/src/psphotFindDetections.c
===================================================================
--- /branches/eam_branches/ipp-20101205/psphot/src/psphotFindDetections.c	(revision 30141)
+++ /branches/eam_branches/ipp-20101205/psphot/src/psphotFindDetections.c	(revision 30142)
@@ -108,4 +108,6 @@
     }
 
+    // XXX do a second (or third?) pass with rebinning (to detected more extended sources)
+
     psFree (significance);
 
Index: /branches/eam_branches/ipp-20101205/psphot/src/psphotMergeSources.c
===================================================================
--- /branches/eam_branches/ipp-20101205/psphot/src/psphotMergeSources.c	(revision 30141)
+++ /branches/eam_branches/ipp-20101205/psphot/src/psphotMergeSources.c	(revision 30142)
@@ -513,5 +513,99 @@
     }
 
-    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;
+}
+
+// copy the detections from one pmFPAfile to another
+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;
+}
+
+// add newly selected sources to the existing list of sources
+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?");
+
+    // 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
+    
+    // XXX currently, this is only used by psphotStackReadout (sources go on allSources so that psphotChoosePSF can be called repeatedly)
+    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
+    }
+
+    // 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;
+      
+      // does this copy all model data?
+
+      // drop the references to the original image pixels:
+      // pmSourceFreePixels (sourceOut);
+
+      // allocate image, weight, mask for the new image for each peak (square of radius OUTER)
+      pmSourceRedefinePixels (sourceOut, readout, sourceOut->peak->x, sourceOut->peak->y, sourceSrc->fitRadius, true);
+
+      // XXX source ID, imageID : how are they really used?
+      sourceOut->imageID = sourceSrc->imageID;
+      // P_PM_SOURCE_SET_ID(source, i);
+
+      psArrayAdd (detections->allSources, 100, sourceOut);
+    }
+    psLogMsg ("psphot", 3, "%ld known sources supplied", detections->allSources->n);
+
+
+    return true;
+}
+
Index: /branches/eam_branches/ipp-20101205/psphot/src/psphotRadialApertures.c
===================================================================
--- /branches/eam_branches/ipp-20101205/psphot/src/psphotRadialApertures.c	(revision 30141)
+++ /branches/eam_branches/ipp-20101205/psphot/src/psphotRadialApertures.c	(revision 30142)
@@ -137,8 +137,14 @@
 bool psphotRadialApertureSource (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal, const psVector *aperRadii, int entry) {
 
-    psAssert(source->radialAper->data[entry] == NULL, "why is this already defined?");
+    // if we are a child source, save the results to the parent source radial aperture array
+    psArray *radialAperSet = source->radialAper;
+    if (source->parent) {
+	radialAperSet = source->parent->radialAper;
+    }
+
+    psAssert(radialAperSet->data[entry] == NULL, "why is this already defined?");
 
     pmSourceRadialApertures *radialAper = pmSourceRadialAperturesAlloc ();
-    source->radialAper->data[entry] = radialAper;
+    radialAperSet->data[entry] = radialAper;
 
     // storage for the derived pixel values
Index: /branches/eam_branches/ipp-20101205/psphot/src/psphotStackReadout.c
===================================================================
--- /branches/eam_branches/ipp-20101205/psphot/src/psphotStackReadout.c	(revision 30141)
+++ /branches/eam_branches/ipp-20101205/psphot/src/psphotStackReadout.c	(revision 30142)
@@ -190,4 +190,7 @@
     psphotSourceSize (config, view, STACK_SRC, TRUE);
 
+    // XXX do we want to do a preliminary (unconvolved) model fit here, and then 
+    // do a second detection pass? (like standard psphot)
+
     // measure aperture photometry corrections
     if (!psphotApResid (config, view, STACK_SRC)) {
@@ -209,5 +212,5 @@
 
     // copy the detections from SRC to OUT (for radial aperture photometry) 
-    if (!psphotCopySources (config, view, STACK_OUT, STACK_SRC)) {
+    if (!psphotSourceChildren (config, view, STACK_OUT, STACK_SRC)) {
 	psFree(objects);
 	psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
@@ -217,10 +220,15 @@
     bool smoothAgain = true;
     for (int nMatchedPSF = 0; smoothAgain; nMatchedPSF++) {
-	psphotRedefinePixels (config, view, STACK_OUT);
-
+
+	// XXX we probably can drop this if we redefine the pixels in CopySources
+	// psphotRedefinePixels (config, view, STACK_OUT);
+
+	// re-measure the PSF for the smoothed image  
 	psphotChoosePSF (config, view, STACK_OUT, false);
 
+	// this is necessary to update the models based on the new PSF
 	psphotResetModels (config, view, STACK_OUT);
 
+	// this is necessary to get the right normalization for the new models
 	psphotFitSourcesLinear (config, view, STACK_OUT, false);
 
@@ -228,6 +236,8 @@
 	psphotRadialAperturesByObject (config, objects, view, STACK_OUT, nMatchedPSF); 
 
+	// replace the flux in the image so it is returned to its original state
 	psphotReplaceAllSources (config, view, STACK_OUT);
 
+	// smooth to the next FWHM, or set 'smoothAgain' to false if no more 
 	psphotStackMatchPSFsNext(&smoothAgain, config, view, STACK_OUT, nMatchedPSF);
     }
