Index: trunk/psModules/src/config/pmConfigMask.c
===================================================================
--- trunk/psModules/src/config/pmConfigMask.c	(revision 41565)
+++ trunk/psModules/src/config/pmConfigMask.c	(revision 41705)
@@ -33,5 +33,5 @@
     { "SPIKE",     NULL,       0x08, false  }, // Pixel contains a diffraction spike
     { "GHOST",     NULL,       0x08, false  }, // Pixel contains an optical ghost
-    { "STREAK",    NULL,       0x08, false  }, // Pixel contains streak data
+    { "CROSSTALK", NULL,       0x08, false  }, // Pixel contains crosstalk data
     { "STARCORE",  NULL,       0x08, false  }, // Pixel contains a bright star core
     // Effects of convolution and interpolation
Index: trunk/psModules/src/objects/pmSourceIO_Glints.c
===================================================================
--- trunk/psModules/src/objects/pmSourceIO_Glints.c	(revision 41565)
+++ trunk/psModules/src/objects/pmSourceIO_Glints.c	(revision 41705)
@@ -175,5 +175,5 @@
 
 	        double glintLength = GLINT_LENGTH_MAG_SLOPE*(GLINT_LENGTH_MAG_ZERO - star->Mag);
-                double glintAngle = 0;
+                double glintAngle = 0.;
 
                 //Besides brightness, the length of the glints also depends on the position of the star compared to the focal plane. But, seemingly only for stars closer than about 30k pixels
Index: trunk/psModules/src/objects/pmSourceMasks.h
===================================================================
--- trunk/psModules/src/objects/pmSourceMasks.h	(revision 41565)
+++ trunk/psModules/src/objects/pmSourceMasks.h	(revision 41705)
@@ -70,4 +70,7 @@
     PM_SOURCE_MODE2_EXT_FITS_NONE         = 0x00400000, ///< ALL of the model fits failed
     
+    PM_SOURCE_MODE2_ON_GHOST      	  = 0x00800000, ///< > 25% of (PSF-weighted) pixels land on ghost
+    PM_SOURCE_MODE2_ON_CROSSTALK      	  = 0x01000000, ///< peaks land on electronic crostalk
+
     
 } pmSourceMode2;
Index: trunk/psModules/src/objects/pmSourcePhotometry.c
===================================================================
--- trunk/psModules/src/objects/pmSourcePhotometry.c	(revision 41565)
+++ trunk/psModules/src/objects/pmSourcePhotometry.c	(revision 41705)
@@ -60,4 +60,5 @@
 static psImageMaskType maskGhost    = 0;
 static psImageMaskType maskGlint    = 0;
+static psImageMaskType maskCrosstalk    = 0;
 
 bool pmSourceMagnitudesInit (pmConfig *config, psMetadata *recipe)
@@ -74,4 +75,5 @@
 	maskGhost    = pmConfigMaskGet("GHOST", config);
 	maskGlint    = pmConfigMaskGet("GHOST", config);
+	maskCrosstalk    = pmConfigMaskGet("CROSSTALK", config);
 	maskSuspect  = maskSpike | maskStarCore | maskBurntool | maskConvPoor;
     }
@@ -437,4 +439,5 @@
     float burntoolSum = 0;
     float convpoorSum = 0;
+    float ghostSum = 0;
 
     int Xo, Yo, dP;
@@ -520,4 +523,8 @@
 	    }
 	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskGhost) {
+		ghostSum += 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;
@@ -539,4 +546,7 @@
     if ((starcoreSum/modelSum) > 0.25) {
 	source->mode2 |= PM_SOURCE_MODE2_ON_STARCORE;
+    }
+    if ((ghostSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_GHOST;
     }
     if ((burntoolSum/modelSum) > 0.25) {
@@ -582,4 +592,146 @@
 	    source->mode |= PM_SOURCE_MODE_ON_SPIKE;
 	}
+	if (maskValue & maskCrosstalk) {
+	    source->mode2 |= PM_SOURCE_MODE2_ON_CROSSTALK;
+	}
+    }
+    return (true);
+}
+
+// return source aperture magnitude
+bool pmSourceMaskEval (pmSource *source, psImage *mask, psImageMaskType maskVal)
+{
+    PS_ASSERT_PTR_NON_NULL(source, false);
+    source->pixWeightNotBad = NAN;
+    source->pixWeightNotPoor = NAN;
+
+    PS_ASSERT_PTR_NON_NULL(mask, false);
+
+    float modelSum = 0;
+    float spikeSum = 0;
+    float starcoreSum = 0;
+    float burntoolSum = 0;
+    float convpoorSum = 0;
+    float ghostSum = 0;
+
+    int Xo, Yo, dP;
+    int dX, DX, NX;
+    int dY, DY, NY;
+
+    float radius=10.;
+    float radius2 = PS_SQR(radius);
+
+    // the model function returns the source flux at a position
+    psVector *coord = psVectorAlloc(2, PS_TYPE_F32);
+
+    Xo = source->peak->x;
+    Yo = source->peak->y;
+
+    dX = Xo - mask->col0;
+    dP = mask->numCols - dX;
+    DX = PS_MAX(dX, dP);
+    NX = mask->numCols;
+
+    dY = Yo - mask->row0;
+    dP = mask->numRows - dY;
+    DY = PS_MAX(dY, dP);
+    NY = mask->numRows;
+
+    psImageMaskType maskBad = maskVal;
+    maskBad &= ~maskSuspect;
+
+    // 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;
+
+            coord->data.F32[0] = (psF32) (ix + Xo);
+            coord->data.F32[1] = (psF32) (iy + Yo);
+
+            modelSum += 1.;
+            // include count only the unmasked pixels within the image area
+            if (mx < 0) continue;
+            if (my < 0) continue;
+            if (mx >= NX) continue;
+            if (my >= NY) continue;
+
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskSpike) {
+		spikeSum += 1.;
+	    }
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskStarCore) {
+		starcoreSum += 1.;
+	    }
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskGhost) {
+		ghostSum += 1.;
+	    }
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskBurntool) {
+		burntoolSum += 1.;
+	    }
+	    // count pixels which are masked with an mask bit (bad or poor)
+            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskConvPoor) {
+		convpoorSum += 1.;
+	    }
+        }
+    }
+    psFree (coord);
+
+    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 ((ghostSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_GHOST;
+    }
+    if ((burntoolSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_BURNTOOL;
+    }
+    if ((convpoorSum/modelSum) > 0.25) {
+	source->mode2 |= PM_SOURCE_MODE2_ON_CONVPOOR;
+    }
+
+    // Check that if the peak is on/off a ghost, glint, or diffraction spike.  In regular IPP
+    // processing, these values are only set in the image mask after the 'camera' stage
+
+    // need to access the parent if we are looking at a subimage (likely)
+    psImage *chipImage = (source->pixels == NULL) ? source->pixels : (psImage *) source->pixels->parent;
+
+    bool onChip = true;
+    onChip &= (Xo >= 0);
+    onChip &= (Xo < chipImage->numCols);
+    onChip &= (Yo >= 0);
+    onChip &= (Yo < chipImage->numRows);
+    if (!onChip) {
+	// if the source is off the edge of the chip, raise a different bit?
+	source->mode |= PM_SOURCE_MODE_OFF_CHIP;
+    } else {
+	int xMask = Xo - mask->col0;
+	int yMask = Yo - mask->row0;
+	psImageMaskType maskValue = mask->data.PS_TYPE_IMAGE_MASK_DATA[yMask][xMask];
+	if (maskValue & maskGhost) {
+	    source->mode |= PM_SOURCE_MODE_ON_GHOST;
+	}
+	pmSourceMode PM_SOURCE_MODE_ON_GLINT = PM_SOURCE_MODE_ON_GHOST;
+	if (maskValue & maskGlint) {
+	    source->mode |= PM_SOURCE_MODE_ON_GLINT;
+	}
+	if (maskValue & maskCrosstalk) {
+	    source->mode2 |= PM_SOURCE_MODE2_ON_CROSSTALK;
+	}
+	if (maskValue & maskSpike) {
+	    source->mode |= PM_SOURCE_MODE_ON_SPIKE;
+	}
     }
     return (true);
Index: trunk/psModules/src/objects/pmSourcePhotometry.h
===================================================================
--- trunk/psModules/src/objects/pmSourcePhotometry.h	(revision 41565)
+++ trunk/psModules/src/objects/pmSourcePhotometry.h	(revision 41705)
@@ -77,4 +77,5 @@
 
 bool pmSourcePixelWeight (pmSource *source, pmModel *model, psImage *mask, psImageMaskType maskVal, float radius);
+bool pmSourceMaskEval (pmSource *source, psImage *mask, psImageMaskType maskVal);
 
 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight, psImageMaskType maskVal);
