Index: trunk/psModules/src/objects/pmSource.c
===================================================================
--- trunk/psModules/src/objects/pmSource.c	(revision 29935)
+++ trunk/psModules/src/objects/pmSource.c	(revision 30621)
@@ -61,5 +61,5 @@
     psFree(tmp->moments);
     psFree(tmp->diffStats);
-    psFree(tmp->radial);
+    psFree(tmp->radialAper);
     psFree(tmp->blends);
     psTrace("psModules.objects", 10, "---- end ----\n");
@@ -126,5 +126,6 @@
     source->extpars = NULL;
     source->diffStats = NULL;
-    source->radial = NULL;
+    source->radialAper = NULL;
+    source->parent = NULL;
 
     source->region = psRegionSet(NAN, NAN, NAN, NAN);
@@ -159,5 +160,5 @@
 affecting the original.  This Copy can be used to allow multiple fit attempts on the same
 object.  The pixels, variance, and mask arrays all point to the same original subarrays.  The
-peak and moments point at the original values.
+peak and moments point at the original values.  The models, blends, and XXX are NOT copied
 *****************************************************************************/
 pmSource *pmSourceCopy(pmSource *in)
@@ -167,7 +168,4 @@
     }
     pmSource *source = pmSourceAlloc ();
-
-    // keep the original ID so we can find map back to the original
-    P_PM_SOURCE_SET_ID(source, in->id);
 
     // peak has the same values as the original
@@ -203,50 +201,4 @@
 }
 
-/******************************************************************************
-pmSourceCopyData(): this creates a new, duplicate source with the same parameters as the
-original (but is actually a new source at the same location)
-*****************************************************************************/
-pmSource *pmSourceCopyData(pmSource *in)
-{
-    if (in == NULL) {
-        return(NULL);
-    }
-    // this copy is used to allow multiple fit attempts on the
-    // same object.  the pixels, variance, and mask arrays all point to
-    // the same original subarrays.  the peak and moments point at
-    // the original values.
-    pmSource *source = pmSourceAlloc ();
-
-    // this is actually the same peak as the original, is this the correct way to handle this?
-    if (in->peak != NULL) {
-        source->peak = pmPeakAlloc (in->peak->x, in->peak->y, in->peak->value, in->peak->type);
-        source->peak->xf = in->peak->xf;
-        source->peak->yf = in->peak->yf;
-        source->peak->flux = in->peak->flux;
-        source->peak->SN = in->peak->SN;
-    }
-
-    // copy the values in the moments structure
-    if (in->moments != NULL) {
-        source->moments  =  pmMomentsAlloc();
-        *source->moments = *in->moments;
-    }
-
-    // These images are all views to the parent.
-    // We want a new view, but pointing at the same pixels.
-    source->pixels   = psImageCopyView(NULL, in->pixels);
-    source->variance   = psImageCopyView(NULL, in->variance);
-    source->maskView = in->maskView ? psImageCopyView(NULL, in->maskView) : NULL;
-
-    // the maskObj is a unique mask array; create a new mask image
-    source->maskObj = in->maskObj ? psImageCopy (NULL, in->maskObj, PS_TYPE_IMAGE_MASK) : NULL;
-
-    source->type = in->type;
-    source->mode = in->mode;
-    source->imageID = in->imageID;
-
-    return(source);
-}
-
 // x,y are defined in the parent image coords of readout->image
 bool pmSourceDefinePixels(pmSource *mySource,
@@ -300,4 +252,5 @@
     newRegion = psRegionForImage (readout->image, newRegion);
 
+    // re-define if required by region or absence of pixels
     extend = false;
     extend |= (int)(newRegion.x0) < (int)(mySource->region.x0);
@@ -335,4 +288,37 @@
     }
     return extend;
+}
+
+bool pmSourceRedefinePixelsByRegion(pmSource *mySource,
+				    const pmReadout *readout,
+				    psRegion newRegion)
+{
+    PS_ASSERT_PTR_NON_NULL(mySource, false);
+    PS_ASSERT_PTR_NON_NULL(readout, false);
+    PS_ASSERT_PTR_NON_NULL(readout->image, false);
+
+    // re-create the subimage
+    psFree (mySource->pixels);
+    psFree (mySource->variance);
+    psFree (mySource->maskView);
+	
+    mySource->pixels   = psImageSubset(readout->image,    newRegion);
+    mySource->variance = psImageSubset(readout->variance, newRegion);
+    mySource->maskView = psImageSubset(readout->mask,     newRegion);
+    mySource->region   = newRegion;
+
+    // re-copy the main mask pixels.  NOTE: the user will need to reset the object mask
+    // pixels (eg, with psImageKeepCircle)
+    mySource->maskObj = psImageCopy (mySource->maskObj, mySource->maskView, PS_TYPE_IMAGE_MASK);
+
+    // drop the old modelFlux pixels and force the user to re-create
+    psFree (mySource->modelFlux);
+    mySource->modelFlux = NULL;
+
+    // drop the old psfImage pixels and force the user to re-create
+    psFree (mySource->psfImage);
+    mySource->psfImage = NULL;
+
+    return true;
 }
 
@@ -675,5 +661,5 @@
             if ((source->moments->SN > PSF_SN_LIM) && (radius < PSF_CLUMP_NSIGMA)) {
                 source->type = PM_SOURCE_TYPE_STAR;
-                source->mode |= PM_SOURCE_MODE_PSFSTAR;
+                source->tmpFlags |= PM_SOURCE_TMPF_CANDIDATE_PSFSTAR;
                 Npsf ++;
                 continue;
@@ -934,6 +920,5 @@
 }
 
-// construct a realization of the source model
-// XXX this function should optionally save an existing psf image from modelFlux
+// construct a realization of the PSF model at the location of this source
 bool pmSourceCachePSF (pmSource *source, psImageMaskType maskVal) {
     PS_ASSERT_PTR_NON_NULL(source, false);
@@ -1020,12 +1005,10 @@
     }
 
-    if (!addNoise) {
-	if (add) {
-	    status = pmModelAddWithOffset (target, source->maskObj, model, PM_MODEL_OP_FULL, maskVal, dx, dy);
-	    source->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
-	} else {
-	    status = pmModelSubWithOffset (target, source->maskObj, model, PM_MODEL_OP_FULL, maskVal, dx, dy);
-	    source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
-	}
+    if (add) {
+	status = pmModelAddWithOffset (target, source->maskObj, model, PM_MODEL_OP_FULL, maskVal, dx, dy);
+	source->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
+    } else {
+	status = pmModelSubWithOffset (target, source->maskObj, model, PM_MODEL_OP_FULL, maskVal, dx, dy);
+	source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
     }
 
