Index: branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.c
===================================================================
--- branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.c	(revision 41813)
+++ branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.c	(revision 41814)
@@ -340,4 +340,11 @@
     psVector *yResGood = psVectorAllocEmpty (match->n, PS_TYPE_F32);
 
+    // we measure the stdev of the median residual in NxN bins.
+    // use only valid (not NAN) measurements
+    psVector *xPosValid = psVectorAllocEmpty (match->n, PS_TYPE_F32);
+    psVector *yPosValid = psVectorAllocEmpty (match->n, PS_TYPE_F32);
+    psVector *xResValid = psVectorAllocEmpty (match->n, PS_TYPE_F32);
+    psVector *yResValid = psVectorAllocEmpty (match->n, PS_TYPE_F32);
+
     for (int i = 0; i < match->n; i++) {
         if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;
@@ -345,4 +352,18 @@
         pmAstromObj *rawStar = raw->data[pair->raw];
         if (!isfinite(rawStar->dMag)) continue;
+
+	bool isValid = true;
+	isValid = isValid & isfinite (xFit->data.F32[i]);
+	isValid = isValid & isfinite (yFit->data.F32[i]);
+	isValid = isValid & isfinite (xRes->data.F32[i]);
+	isValid = isValid & isfinite (yRes->data.F32[i]);
+	if (isValid) {
+	  psVectorAppend (xPosValid, xFit->data.F32[i]);
+	  psVectorAppend (yPosValid, yFit->data.F32[i]);
+	  psVectorAppend (xResValid, xRes->data.F32[i]);
+	  psVectorAppend (yResValid, yRes->data.F32[i]);
+	}
+
+	// for the systematic error, use only high S/N stars
         if (rawStar->dMag > 0.02) continue;
 
@@ -377,10 +398,10 @@
       results->dYrange = pmAstromVectorRange (yResGood, 0.1, 0.9, results->yStats->clippedStdev);
 
-      results->dXstdev = pmAstrom2DSystematics (xFit, yFit, xRes);
-      results->dYstdev = pmAstrom2DSystematics (xFit, yFit, yRes);
-    }
-
-    psTrace ("psModules.astrom", 3, "dXsys: %f, dXrange: %f\n", results->dXsys, results->dXrange);
-    psTrace ("psModules.astrom", 3, "dYsys: %f, dYrange: %f\n", results->dYsys, results->dYrange);
+      results->dXstdev = pmAstrom2DSystematics (xPosValid, yPosValid, xResValid);
+      results->dYstdev = pmAstrom2DSystematics (xPosValid, yPosValid, yResValid);
+    }
+
+    psTrace ("psModules.astrom", 3, "dXsys: %f, dXrange: %f, dXstdev: %f\n", results->dXsys, results->dXrange, results->dXstdev);
+    psTrace ("psModules.astrom", 3, "dYsys: %f, dYrange: %f, dYstdev: %f\n", results->dYsys, results->dYrange, results->dYstdev);
 
     psFree (xErr);
@@ -390,4 +411,8 @@
     psFree (xResGood);
     psFree (yResGood);
+    psFree (xPosValid);
+    psFree (yPosValid);
+    psFree (xResValid);
+    psFree (yResValid);
 
     psFree (x);
Index: branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.h
===================================================================
--- branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.h	(revision 41813)
+++ branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.h	(revision 41814)
@@ -102,4 +102,6 @@
     double  dXrange;			///< 10% - 90% range X residuals (unmasked, high S/N)
     double  dYrange;			///< 10% - 90% range Y residuals (unmasked, high S/N)
+    double  dXstdev;			///< stdev of median residual in NxN bins
+    double  dYstdev;			///< stdev of median residual in NxN bins
 }
 pmAstromFitResults;
