Index: /branches/eam_branches/ipp-20230313/psModules/src/objects/pmSourceMoments.c
===================================================================
--- /branches/eam_branches/ipp-20230313/psModules/src/objects/pmSourceMoments.c	(revision 42510)
+++ /branches/eam_branches/ipp-20230313/psModules/src/objects/pmSourceMoments.c	(revision 42511)
@@ -231,10 +231,22 @@
     }
 
+    // For faint externally-supplied sources, the centroids are unreliable.
+    // In those cases, we should keep the peak position instead of the centroid position.
+    bool skipCentroid = false;
+    skipCentroid |= (source->mode  & PM_SOURCE_MODE_EXTERNAL); // skip externally supplied positions
+    skipCentroid |= (source->mode2 & PM_SOURCE_MODE2_MATCHED); // skip sources defined by other image positions
+
     // if we have less than (1/4) of the possible pixels (in circle or box), force a retry
     int minPixels = PS_MIN(0.75*R2, source->pixels->numCols*source->pixels->numRows/4.0);
 
     // XXX EAM - the limit is a bit arbitrary.  make it user defined?
-    if ((numPixels < minPixels) || (Sum <= 0)) {
+    if (numPixels < minPixels) {
 	psTrace ("psModules.objects", 3, "insufficient valid pixels (%d vs %d; %f) for source\n", numPixels, minPixels, Sum);
+	return (false);
+    }
+
+    // Skip negative-sum sources, but only if the sources are not forced (externally supplied)
+    if (!skipCentroid && (Sum <= 0)) {
+	psTrace ("psModules.objects", 3, "insufficient significant pixels (%d vs %d; %f) for source\n", numPixels, minPixels, Sum);
 	return (false);
     }
@@ -243,13 +255,14 @@
     float Mx = X1/Sum;
     float My = Y1/Sum;
-    if ((fabs(Mx) > radius) || (fabs(My) > radius)) {
-	psTrace ("psModules.objects", 3, "extreme centroid swing; invalid peak %d, %d\n", source->peak->x, source->peak->y);
-	return (false);
-    }
     if ((fabs(Mx) > 2.0) || (fabs(My) > 2.0)) {
 	psTrace ("psModules.objects", 3, " big centroid swing; ok peak? %d, %d\n", source->peak->x, source->peak->y);
     }
-
     psTrace ("psModules.objects", 5, "id: %d, sky: %f  Mx: %f  My: %f  Sum: %f  X1: %f  Y1: %f  Npix: %d\n", source->id, sky, Mx, My, Sum, X1, Y1, numPixels);
+
+    // XXX EAM : I need to move this block so I can use SN to choose if we keep the centroids or not
+    source->moments->Sum = Sum;
+    source->moments->SN  = Sum / sqrt(Var);
+    source->moments->Peak = peakPixel;
+    source->moments->nPixels = numPixels;
 
     // add back offset of peak in primary image
@@ -258,21 +271,23 @@
     // 0.5 PIX: moments are calculated using the pixel index and converted here to pixel coords
 
-    // we only update the centroid if the position is not supplied from elsewhere
-    bool skipCentroid = false;
-    skipCentroid |= (source->mode  & PM_SOURCE_MODE_EXTERNAL); // skip externally supplied positions
-    skipCentroid |= (source->mode2 & PM_SOURCE_MODE2_MATCHED); // skip sources defined by other image positions
-
-    if (skipCentroid) {
+    // XXX for a test, do NOT skip the centroid for relatively strong sources, even if forced
+    // XXX this is a somewhat arbitrary limit.  use PSF_SN_LIM (see below) instead?
+    if (skipCentroid && (source->moments->SN < 25)) {
 	source->moments->Mx = source->peak->xf;
 	source->moments->My = source->peak->yf;
     } else {
+	if ((fabs(Mx) > radius) || (fabs(My) > radius)) {
+	    psTrace ("psModules.objects", 3, "extreme centroid swing; invalid peak %d, %d\n", source->peak->x, source->peak->y);
+
+	    // XXX should we really be rejecting these sources, or just keeping the peak position?
+	    return (false);
+
+	    source->moments->Mx = source->peak->xf;
+	    source->moments->My = source->peak->yf;
+	    return (true);
+	}
 	source->moments->Mx = Mx + xGuess;
 	source->moments->My = My + yGuess;
     }
-
-    source->moments->Sum = Sum;
-    source->moments->SN  = Sum / sqrt(Var);
-    source->moments->Peak = peakPixel;
-    source->moments->nPixels = numPixels;
 
     return true;
