Index: trunk/psphot/src/psphot.h
===================================================================
--- trunk/psphot/src/psphot.h	(revision 34353)
+++ trunk/psphot/src/psphot.h	(revision 34354)
@@ -368,4 +368,5 @@
 bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, const char *filerule, int index);
 bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS);
+bool psphotDropBadMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects);
 
 bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final);
Index: trunk/psphot/src/psphotSourceMatch.c
===================================================================
--- trunk/psphot/src/psphotSourceMatch.c	(revision 34353)
+++ trunk/psphot/src/psphotSourceMatch.c	(revision 34354)
@@ -558,2 +558,63 @@
     return matchInfo;
 }
+
+bool psphotDropBadMatchedSources (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects) {
+
+    bool status = false;
+
+    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Drop Bad Matched Sources ---");
+
+    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+
+    // select the appropriate recipe information
+    bool keepBadMatches = psMetadataLookupBool (&status, recipe, "PSPHOT.STACK.KEEP.BAD.MATCHES");
+    if (!status) {
+        keepBadMatches = true;
+    }
+
+    if (keepBadMatches) {
+        psLogMsg ("psphot", PS_LOG_INFO, "keeping bad matches");
+        return true;
+    }
+
+    int numImages = psphotFileruleCount(config, filerule);
+    psVector *dropped = psVectorAlloc(numImages, PS_TYPE_U32);
+    psVectorInit(dropped, 0);
+
+    int nDropped = 0;
+    for (int i = 0; i < objects->n; i++) { 
+        pmPhotObj *obj = objects->data[i]; 
+
+        // traverse the array from the end so that sources don't move until after we've processed them
+	for (int j = obj->sources->n - 1; j >= 0; j--) {
+
+	    pmSource *source = obj->sources->data[j]; 
+            // This applies only to matched sources
+            if (!(source->mode2 & PM_SOURCE_MODE2_MATCHED)) continue;
+
+            if (isfinite(source->apFlux)) continue;
+
+            psTrace ("psphot", 7, "Dropping matched source from image %d at (%d, %d) no valid flux",
+                source->imageID, source->peak->x, source->peak->y);
+
+            psAssert(source->imageID >= 0 && source->imageID < numImages, "bad imageID %d", source->imageID);
+
+            dropped->data.U32[source->imageID]++;
+            
+            nDropped++;
+
+            psArrayRemoveIndex(obj->sources, j);
+        }
+    }
+
+    psLogMsg ("psphot", PS_LOG_DETAIL, "Dropped %d matched sources with no valid flux", nDropped);
+    psLogMsg ("psphot", PS_LOG_DETAIL, "       Input  Num Dropped");
+    for (int i=0; i<numImages; i++) {
+        psLogMsg ("psphot", PS_LOG_DETAIL, "    %8d     %8d", i, dropped->data.U32[i]);
+    }
+    psFree(dropped);
+
+    return true;
+}
+
+
Index: trunk/psphot/src/psphotStackReadout.c
===================================================================
--- trunk/psphot/src/psphotStackReadout.c	(revision 34353)
+++ trunk/psphot/src/psphotStackReadout.c	(revision 34354)
@@ -355,4 +355,7 @@
 
     psMemDump("psfstats");
+
+    // drop matched sources without any useful measurements
+    psphotDropBadMatchedSources (config, view, STACK_SRC, objects);
 
     // measure elliptical apertures, petrosians (objects sorted by S/N)
