Index: branches/eam_branches/ipp-20110213/psModules/src/objects/pmPSF.c
===================================================================
--- branches/eam_branches/ipp-20110213/psModules/src/objects/pmPSF.c	(revision 30763)
+++ branches/eam_branches/ipp-20110213/psModules/src/objects/pmPSF.c	(revision 30772)
@@ -430,4 +430,9 @@
         return NAN;
     }
+
+    // get the model full-width at half-max
+    float fwhmMajor = 2*model->modelRadius (model->params, 0.5);
+
+# if (0)
     psF32 *params = model->params->data.F32; // Model parameters
     psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO); // Ellipse axes
@@ -439,3 +444,9 @@
 
     return fwhm;
-}
+# else
+
+    psFree(model);
+
+    return fwhmMajor;
+# endif
+}
Index: branches/eam_branches/ipp-20110213/psModules/src/objects/pmPSFtryFitPSF.c
===================================================================
--- branches/eam_branches/ipp-20110213/psModules/src/objects/pmPSFtryFitPSF.c	(revision 30763)
+++ branches/eam_branches/ipp-20110213/psModules/src/objects/pmPSFtryFitPSF.c	(revision 30772)
@@ -109,5 +109,5 @@
 
 	// This function calculates the psf and aperture magnitudes
-        status = pmSourceMagnitudes (source, psfTry->psf, PM_SOURCE_PHOT_INTERP, maskVal, markVal); // raw PSF mag, AP mag
+        status = pmSourceMagnitudes (source, psfTry->psf, PM_SOURCE_PHOT_INTERP, maskVal, markVal, options->apRadius); // raw PSF mag, AP mag
         if (!status || isnan(source->apMag)) {
             psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
Index: branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourceMasks.h
===================================================================
--- branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourceMasks.h	(revision 30763)
+++ branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourceMasks.h	(revision 30772)
@@ -46,4 +46,9 @@
     PM_SOURCE_MODE2_DIFF_WITH_DOUBLE = 0x00000002, ///< diff source matched to positive detections in both images
     PM_SOURCE_MODE2_MATCHED          = 0x00000004, ///< diff source matched to positive detections in both images
+
+    PM_SOURCE_MODE2_ON_SPIKE         = 0x00000008, ///< > 25% of (PSF-weighted) pixels land on diffraction spike
+    PM_SOURCE_MODE2_ON_STARCORE      = 0x00000010, ///< > 25% of (PSF-weighted) pixels land on starcore
+    PM_SOURCE_MODE2_ON_BURNTOOL      = 0x00000020, ///< > 25% of (PSF-weighted) pixels land on burntool
+    PM_SOURCE_MODE2_ON_CONVPOOR      = 0x00000040, ///< > 25% of (PSF-weighted) pixels land on convpoor
 } pmSourceMode2;
 
Index: branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourcePhotometry.c
===================================================================
--- branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourcePhotometry.c	(revision 30763)
+++ branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourcePhotometry.c	(revision 30772)
@@ -23,4 +23,5 @@
 #include "pmFPAMaskWeight.h"
 
+#include "pmConfigMask.h"
 #include "pmTrend2D.h"
 #include "pmResiduals.h"
@@ -49,10 +50,26 @@
 static float AP_MIN_SN = 0.0;
 
-bool pmSourceMagnitudesInit (psMetadata *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
+// make this a bit more clever and dynamic
+static psImageMaskType maskSuspect  = 0;
+static psImageMaskType maskSpike    = 0;
+static psImageMaskType maskStarCore = 0;
+static psImageMaskType maskBurntool = 0;
+static psImageMaskType maskConvPoor = 0;
+
+bool pmSourceMagnitudesInit (pmConfig *config, psMetadata *recipe)
+{
+    PS_ASSERT_PTR_NON_NULL(recipe, false);
     bool status;
 
-    float limit = psMetadataLookupF32 (&status, config, "AP_MIN_SN");
+    // we are going to test specially against these poor values
+    if (config) {
+	maskSpike    = pmConfigMaskGet("SPIKE", config);
+	maskStarCore = pmConfigMaskGet("STARCORE", config);
+	maskBurntool = pmConfigMaskGet("BURNTOOL", config);
+	maskConvPoor = pmConfigMaskGet("CONV.POOR", config);
+	maskSuspect  = maskSpike | maskStarCore | maskBurntool | maskConvPoor;
+    }
+
+    float limit = psMetadataLookupF32 (&status, recipe, "AP_MIN_SN");
     if (status) {
         AP_MIN_SN = limit;
@@ -77,5 +94,5 @@
 // XXX masked region should be (optionally) elliptical
 // if mode is PM_SOURCE_PHOT_PSFONLY, we skip all other magnitudes
-bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal)
+bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal, float radius)
 {
     PS_ASSERT_PTR_NON_NULL(source, false);
@@ -166,5 +183,5 @@
     // measure the contribution of included pixels
     if (mode & PM_SOURCE_PHOT_WEIGHT) {
-        pmSourcePixelWeight (&source->pixWeightNotBad, &source->pixWeightNotPoor, model, source->maskObj, maskVal, markVal);
+        pmSourcePixelWeight (source, model, source->maskObj, maskVal, radius);
     }
 
@@ -342,8 +359,10 @@
 
 // return source aperture magnitude
-bool pmSourcePixelWeight (float *pixWeightNotBad, float *pixWeightNotPoor, pmModel *model, psImage *mask, psImageMaskType maskVal, psImageMaskType markVal)
-{
-    PS_ASSERT_PTR_NON_NULL(pixWeightNotBad, false);
-    PS_ASSERT_PTR_NON_NULL(pixWeightNotPoor, false);
+bool pmSourcePixelWeight (pmSource *source, pmModel *model, psImage *mask, psImageMaskType maskVal, float radius)
+{
+    PS_ASSERT_PTR_NON_NULL(source, false);
+    source->pixWeightNotBad = NAN;
+    source->pixWeightNotPoor = NAN;
+
     PS_ASSERT_PTR_NON_NULL(mask, false);
     PS_ASSERT_PTR_NON_NULL(model, false);
@@ -355,10 +374,14 @@
     float value;
 
+    float spikeSum = 0;
+    float starcoreSum = 0;
+    float burntoolSum = 0;
+    float convpoorSum = 0;
+
     int Xo, Yo, dP;
     int dX, DX, NX;
     int dY, DY, NY;
 
-    *pixWeightNotBad = 0.0;
-    *pixWeightNotPoor = 0.0;
+    float radius2 = PS_SQR(radius);
 
     // we only care about the value of the object model, not the local sky
@@ -387,11 +410,19 @@
     NY = mask->numRows;
 
+    psImageMaskType maskBad = maskVal;
+    maskBad &= ~maskSuspect;
+
     // measure modelSum and validSum.  this function is applied to a sources' subimage.  the
     // value of DX is chosen (see above) to cover the full possible size of the subimage if it
     // were not by an edge; ie, if the source is cut in half by an image edge, we correctly
     // count the virtual pixels off the edge in normalizing the value of the pixWeight
+
+    // we skip any pixels [real or virtual] outside of the specified radius (nominally the aperture radius)
     for (int ix = -DX; ix < DX + 1; ix++) {
+	if (ix > radius) continue;
         int mx = ix + dX;
         for (int iy = -DY; iy < DY + 1; iy++) {
+	    if (iy > radius) continue;
+	    if (ix*ix + iy*iy > radius2) continue;
             int my = iy + dY;
 
@@ -409,19 +440,52 @@
             if (my >= NY) continue;
 
-            if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskVal)) {
+	    // count pixels which are masked only with bad pixels
+            if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskBad)) {
 		notBadSum += value;
 	    }
-            if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & ~markVal)) {
+
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskVal)) {
 		notPoorSum += value;
 	    }
+
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskSpike) {
+		spikeSum += value;
+	    }
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskStarCore) {
+		starcoreSum += value;
+	    }
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskBurntool) {
+		burntoolSum += value;
+	    }
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskConvPoor) {
+		convpoorSum += value;
+	    }
         }
     }
     psFree (coord);
 
-    *pixWeightNotBad  = notBadSum  / modelSum;
-    *pixWeightNotPoor = notPoorSum / modelSum;
-
-    if (false && isfinite(*pixWeightNotBad) && isfinite(*pixWeightNotPoor)) {
-	psAssert (*pixWeightNotBad <= *pixWeightNotPoor, "error: all bad pixels should also be poor");
+    source->pixWeightNotBad  = notBadSum  / modelSum;
+    source->pixWeightNotPoor = notPoorSum / modelSum;
+
+    if ((spikeSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_SPIKE;
+    }
+    if ((starcoreSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_STARCORE;
+    }
+    if ((burntoolSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_BURNTOOL;
+    }
+    if ((convpoorSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_CONVPOOR;
+    }
+
+    if (isfinite(source->pixWeightNotBad) && isfinite(source->pixWeightNotPoor)) {
+	psAssert (source->pixWeightNotBad <= source->pixWeightNotPoor, "error: all bad pixels should also be poor");
     }
 
@@ -431,5 +495,5 @@
 # define FLUX_LIMIT 3.0
 
-// measure stats that may be using in difference images for distinguishing real sources from bad residuals
+// measure stats that may be used in difference images for distinguishing real sources from bad residuals
 bool pmSourceMeasureDiffStats (pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
 {
Index: branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourcePhotometry.h
===================================================================
--- branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourcePhotometry.h	(revision 30763)
+++ branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourcePhotometry.h	(revision 30772)
@@ -64,8 +64,8 @@
 );
 
-bool pmSourceMagnitudesInit (psMetadata *config);
-bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal);
+bool pmSourceMagnitudesInit (pmConfig *config, psMetadata *recipe);
+bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal, float radius);
 
-bool pmSourcePixelWeight (float *pixWeightNotBad, float *pixWeightNotPoor, pmModel *model, psImage *mask, psImageMaskType maskVal, psImageMaskType markVal);
+bool pmSourcePixelWeight (pmSource *source, pmModel *model, psImage *mask, psImageMaskType maskVal, float radius);
 
 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight, psImageMaskType maskVal, const float covarFactor, int nParams);
