Index: /branches/eam_branches/20090715/psphot/src/psphotVisual.c
===================================================================
--- /branches/eam_branches/20090715/psphot/src/psphotVisual.c	(revision 25386)
+++ /branches/eam_branches/20090715/psphot/src/psphotVisual.c	(revision 25387)
@@ -20,8 +20,43 @@
 // these are invoked by the -visual options
 
-static int kapa = -1;
+static int kapa1 = -1;
 static int kapa2 = -1;
 static int kapa3 = -1;
 
+int psphotKapaChannel (int channel) {
+
+    switch (channel) {
+      case 1:
+	if (kapa1 == -1) {
+	    kapa1 = KapaOpenNamedSocket ("kapa", "psphot:images");
+	    if (kapa1 == -1) {
+		fprintf (stderr, "failure to open kapa; visual mode disabled\n");
+		pmVisualSetVisual(false);
+	    }
+	}
+	return kapa1;
+      case 2:
+	if (kapa2 == -1) {
+	    kapa2 = KapaOpenNamedSocket ("kapa", "psphot:plots");
+	    if (kapa2 == -1) {
+		fprintf (stderr, "failure to open kapa; visual mode disabled\n");
+		pmVisualSetVisual(false);
+	    }
+	}
+	return kapa2;
+      case 3:
+	if (kapa3 == -1) {
+	    kapa3 = KapaOpenNamedSocket ("kapa", "psphot:stamps");
+	    if (kapa3 == -1) {
+		fprintf (stderr, "failure to open kapa; visual mode disabled\n");
+		pmVisualSetVisual(false);
+	    }
+	}
+	return kapa3;
+      default:
+	psAbort ("unknown kapa channel");
+    }
+    psAbort ("unknown kapa channel");
+}
 
 bool psphotVisualShowMask (int kapaFD, psImage *inImage, const char *name, int channel) {
@@ -131,14 +166,8 @@
 bool psphotVisualShowImage (pmReadout *readout) {
 
-    if (!pmVisualIsVisual()) return true;
-
-    if (kapa == -1) {
-        kapa = KapaOpenNamedSocket ("kapa", "psphot:images");
-        if (kapa == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
+    // if (!pmVisualIsVisual()) return true;
+
+    int kapa = psphotKapaChannel (1);
+    if (kapa == -1) return false;
 
     // psphotVisualShowMask (kapa, readout->mask, "mask", 2);
@@ -162,12 +191,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        kapa = KapaOpenNamedSocket ("kapa", "psphot:images");
-        if (kapa == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
+    int kapa = psphotKapaChannel (1);
+    if (kapa == -1) return false;
 
     bool status = false;
@@ -197,12 +220,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        kapa = KapaOpenNamedSocket ("kapa", "psphot:images");
-        if (kapa == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
+    int kapa = psphotKapaChannel (1);
+    if (kapa == -1) return false;
 
     // XXX test: image->data.F32[10][10] = 10000;
@@ -226,8 +243,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        fprintf (stderr, "kapa not opened, skipping\n");
-        return false;
-    }
+    int kapa = psphotKapaChannel (1);
+    if (kapa == -1) return false;
 
     psArray *peaks = detections->peaks;
@@ -304,8 +319,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        fprintf (stderr, "kapa not opened, skipping\n");
-        return false;
-    }
+    int kapa = psphotKapaChannel (1);
+    if (kapa == -1) return false;
 
     psArray *footprints = detections->footprints;
@@ -422,8 +435,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        fprintf (stderr, "kapa not opened, skipping\n");
-        return false;
-    }
+    int kapa = psphotKapaChannel (1);
+    if (kapa == -1) return false;
 
     // XXX mark the different source classes with different color/shape dots
@@ -483,16 +494,10 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa3 == -1) {
-        kapa3 = KapaOpenNamedSocket ("kapa", "psphot:plots");
-        if (kapa3 == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
-
-    KapaClearPlots (kapa3);
+    int myKapa = psphotKapaChannel (2);
+    if (myKapa == -1) return false;
+
+    KapaClearPlots (myKapa);
     KapaInitGraph (&graphdata);
-    KapaSetFont (kapa3, "courier", 14);
+    KapaSetFont (myKapa, "courier", 14);
 
     float SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM");
@@ -525,4 +530,6 @@
         }
     }
+    Xmin = PS_MAX(Xmin, -0.1); 
+    Ymin = PS_MAX(Ymin, -0.1); 
 
     // storage vectors for data to be plotted
@@ -572,5 +579,5 @@
     section.y  = 0.00;
     section.name = psStringCopy ("MxxMyy");
-    KapaSetSection (kapa3, &section);
+    KapaSetSection (myKapa, &section);
     psFree (section.name);
 
@@ -580,9 +587,9 @@
     graphdata.xmax = Xmax;
     graphdata.ymax = Ymax;
-    KapaSetLimits (kapa3, &graphdata);
-
-    KapaBox (kapa3, &graphdata);
-    KapaSendLabel (kapa3, "M_xx| (pixels)", KAPA_LABEL_XM);
-    KapaSendLabel (kapa3, "M_yy| (pixels)", KAPA_LABEL_YM);
+    KapaSetLimits (myKapa, &graphdata);
+
+    KapaBox (myKapa, &graphdata);
+    KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM);
+    KapaSendLabel (myKapa, "M_yy| (pixels)", KAPA_LABEL_YM);
 
     graphdata.color = KapaColorByName ("black");
@@ -590,7 +597,7 @@
     graphdata.size = 0.3;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, nF, &graphdata);
-    KapaPlotVector (kapa3, nF, xFaint->data.F32, "x");
-    KapaPlotVector (kapa3, nF, yFaint->data.F32, "y");
+    KapaPrepPlot (myKapa, nF, &graphdata);
+    KapaPlotVector (myKapa, nF, xFaint->data.F32, "x");
+    KapaPlotVector (myKapa, nF, yFaint->data.F32, "y");
 
     graphdata.color = KapaColorByName ("red");
@@ -598,7 +605,7 @@
     graphdata.size = 0.5;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, nB, &graphdata);
-    KapaPlotVector (kapa3, nB, xBright->data.F32, "x");
-    KapaPlotVector (kapa3, nB, yBright->data.F32, "y");
+    KapaPrepPlot (myKapa, nB, &graphdata);
+    KapaPlotVector (myKapa, nB, xBright->data.F32, "x");
+    KapaPlotVector (myKapa, nB, yBright->data.F32, "y");
 
     // second section: MagMyy
@@ -608,5 +615,5 @@
     section.y  = 0.80;
     section.name = psStringCopy ("MagMyy");
-    KapaSetSection (kapa3, &section);
+    KapaSetSection (myKapa, &section);
     psFree (section.name);
 
@@ -616,10 +623,10 @@
     graphdata.ymin = Ymin;
     graphdata.ymax = Ymax;
-    KapaSetLimits (kapa3, &graphdata);
+    KapaSetLimits (myKapa, &graphdata);
 
     strcpy (graphdata.labels, "0210");
-    KapaBox (kapa3, &graphdata);
-    KapaSendLabel (kapa3, "inst mag", KAPA_LABEL_XP);
-    KapaSendLabel (kapa3, "M_yy| (pixels)", KAPA_LABEL_YM);
+    KapaBox (myKapa, &graphdata);
+    KapaSendLabel (myKapa, "inst mag", KAPA_LABEL_XP);
+    KapaSendLabel (myKapa, "M_yy| (pixels)", KAPA_LABEL_YM);
 
     graphdata.color = KapaColorByName ("black");
@@ -627,7 +634,7 @@
     graphdata.size = 0.3;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, nF, &graphdata);
-    KapaPlotVector (kapa3, nF, mFaint->data.F32, "x");
-    KapaPlotVector (kapa3, nF, yFaint->data.F32, "y");
+    KapaPrepPlot (myKapa, nF, &graphdata);
+    KapaPlotVector (myKapa, nF, mFaint->data.F32, "x");
+    KapaPlotVector (myKapa, nF, yFaint->data.F32, "y");
 
     graphdata.color = KapaColorByName ("red");
@@ -635,7 +642,7 @@
     graphdata.size = 0.5;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, nB, &graphdata);
-    KapaPlotVector (kapa3, nB, mBright->data.F32, "x");
-    KapaPlotVector (kapa3, nB, yBright->data.F32, "y");
+    KapaPrepPlot (myKapa, nB, &graphdata);
+    KapaPlotVector (myKapa, nB, mBright->data.F32, "x");
+    KapaPlotVector (myKapa, nB, yBright->data.F32, "y");
 
     // third section: MagMxx
@@ -645,5 +652,5 @@
     section.y  = 0.00;
     section.name = psStringCopy ("MagMxx");
-    KapaSetSection (kapa3, &section);
+    KapaSetSection (myKapa, &section);
     psFree (section.name);
 
@@ -653,10 +660,10 @@
     graphdata.ymin =  -7.9;
     graphdata.ymax = -17.1;
-    KapaSetLimits (kapa3, &graphdata);
+    KapaSetLimits (myKapa, &graphdata);
 
     strcpy (graphdata.labels, "2001");
-    KapaBox (kapa3, &graphdata);
-    KapaSendLabel (kapa3, "M_xx| (pixels)", KAPA_LABEL_XM);
-    KapaSendLabel (kapa3, "inst mag", KAPA_LABEL_YP);
+    KapaBox (myKapa, &graphdata);
+    KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM);
+    KapaSendLabel (myKapa, "inst mag", KAPA_LABEL_YP);
 
     graphdata.color = KapaColorByName ("black");
@@ -664,7 +671,7 @@
     graphdata.size = 0.3;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, nF, &graphdata);
-    KapaPlotVector (kapa3, nF, xFaint->data.F32, "x");
-    KapaPlotVector (kapa3, nF, mFaint->data.F32, "y");
+    KapaPrepPlot (myKapa, nF, &graphdata);
+    KapaPlotVector (myKapa, nF, xFaint->data.F32, "x");
+    KapaPlotVector (myKapa, nF, mFaint->data.F32, "y");
 
     graphdata.color = KapaColorByName ("red");
@@ -672,11 +679,11 @@
     graphdata.size = 0.5;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, nB, &graphdata);
-    KapaPlotVector (kapa3, nB, xBright->data.F32, "x");
-    KapaPlotVector (kapa3, nB, mBright->data.F32, "y");
+    KapaPrepPlot (myKapa, nB, &graphdata);
+    KapaPlotVector (myKapa, nB, xBright->data.F32, "x");
+    KapaPlotVector (myKapa, nB, mBright->data.F32, "y");
 
     // draw N circles to outline the clumps
     {
-        KapaSelectSection (kapa3, "MxxMyy");
+        KapaSelectSection (myKapa, "MxxMyy");
 
         // draw a circle centered on psfX,Y with size of the psf limit
@@ -694,5 +701,5 @@
 	graphdata.xmax = Xmax;
 	graphdata.ymax = Ymax;
-	KapaSetLimits (kapa3, &graphdata);
+	KapaSetLimits (myKapa, &graphdata);
 
         for (int n = 0; n < nRegions; n++) {
@@ -713,47 +720,11 @@
                 yLimit->data.F32[i] = Ry*sin(i*2.0*M_PI/120.0) + psfY;
             }
-            KapaPrepPlot (kapa3, xLimit->n, &graphdata);
-            KapaPlotVector (kapa3, xLimit->n, xLimit->data.F32, "x");
-            KapaPlotVector (kapa3, yLimit->n, yLimit->data.F32, "y");
+            KapaPrepPlot (myKapa, xLimit->n, &graphdata);
+            KapaPlotVector (myKapa, xLimit->n, xLimit->data.F32, "x");
+            KapaPlotVector (myKapa, yLimit->n, yLimit->data.F32, "y");
         }
         psFree (xLimit);
         psFree (yLimit);
     }
-
-# if (0)
-    // *** make a histogram of the source counts in the x and y directions
-    psHistogram *nX = psHistogramAlloc (graphdata.xmin, graphdata.xmax, 50.0);
-    psHistogram *nY = psHistogramAlloc (graphdata.ymin, graphdata.ymax, 50.0);
-    psVectorHistogram (nX, xFaint, NULL, NULL, 0);
-    psVectorHistogram (nY, yFaint, NULL, NULL, 0);
-    psVector *dX = psVectorAlloc (nX->nums->n, PS_TYPE_F32);
-    psVector *vX = psVectorAlloc (nX->nums->n, PS_TYPE_F32);
-    psVector *dY = psVectorAlloc (nY->nums->n, PS_TYPE_F32);
-    psVector *vY = psVectorAlloc (nY->nums->n, PS_TYPE_F32);
-    for (int i = 0; i < nX->nums->n; i++) {
-        dX->data.F32[i] = nX->nums->data.S32[i];
-        vX->data.F32[i] = 0.5*(nX->bounds->data.F32[i] + nX->bounds->data.F32[i+1]);
-    }
-    for (int i = 0; i < nY->nums->n; i++) {
-        dY->data.F32[i] = nY->nums->data.S32[i];
-        vY->data.F32[i] = 0.5*(nY->bounds->data.F32[i] + nY->bounds->data.F32[i+1]);
-    }
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 0;
-    graphdata.size = 0.0;
-    graphdata.style = 0;
-    KapaPrepPlot (kapa3, dX->n, &graphdata);
-    KapaPlotVector (kapa3, dX->n, dX->data.F32, "x");
-    KapaPlotVector (kapa3, vX->n, vX->data.F32, "y");
-
-    psFree (nX);
-    psFree (dX);
-    psFree (vX);
-
-    psFree (nY);
-    psFree (dY);
-    psFree (vY);
-# endif
 
     psFree (xBright);
@@ -775,5 +746,5 @@
 
 // assumes 'kapa' value is checked and set
-bool psphotVisualShowRoughClass_Single (psArray *sources, pmSourceType type, pmSourceMode mode, char *color) {
+bool psphotVisualShowRoughClass_Single (int myKapa, psArray *sources, pmSourceType type, pmSourceMode mode, char *color) {
 
     int Noverlay;
@@ -815,5 +786,5 @@
     }
 
-    KiiLoadOverlay (kapa, overlay, Noverlay, color);
+    KiiLoadOverlay (myKapa, overlay, Noverlay, color);
     FREE (overlay);
 
@@ -825,17 +796,15 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        fprintf (stderr, "kapa not opened, skipping\n");
-        return false;
-    }
-
-    KiiEraseOverlay (kapa, "yellow"); // moments
-
-    psphotVisualShowRoughClass_Single (sources, PM_SOURCE_TYPE_STAR, 0, "red");
-    psphotVisualShowRoughClass_Single (sources, PM_SOURCE_TYPE_EXTENDED, 0, "blue");
-    psphotVisualShowRoughClass_Single (sources, PM_SOURCE_TYPE_DEFECT, 0, "blue");
-    psphotVisualShowRoughClass_Single (sources, PM_SOURCE_TYPE_SATURATED, 0, "red");
-    psphotVisualShowRoughClass_Single (sources, PM_SOURCE_TYPE_STAR, PM_SOURCE_MODE_PSFSTAR, "yellow");
-    psphotVisualShowRoughClass_Single (sources, PM_SOURCE_TYPE_STAR, PM_SOURCE_MODE_SATSTAR, "green");
+    int myKapa = psphotKapaChannel (1);
+    if (myKapa == -1) return false;
+
+    KiiEraseOverlay (myKapa, "yellow"); // moments
+
+    psphotVisualShowRoughClass_Single (myKapa, sources, PM_SOURCE_TYPE_STAR, 0, "red");
+    psphotVisualShowRoughClass_Single (myKapa, sources, PM_SOURCE_TYPE_EXTENDED, 0, "blue");
+    psphotVisualShowRoughClass_Single (myKapa, sources, PM_SOURCE_TYPE_DEFECT, 0, "blue");
+    psphotVisualShowRoughClass_Single (myKapa, sources, PM_SOURCE_TYPE_SATURATED, 0, "red");
+    psphotVisualShowRoughClass_Single (myKapa, sources, PM_SOURCE_TYPE_STAR, PM_SOURCE_MODE_PSFSTAR, "yellow");
+    psphotVisualShowRoughClass_Single (myKapa, sources, PM_SOURCE_TYPE_STAR, PM_SOURCE_MODE_SATSTAR, "green");
 
     // pause and wait for user input:
@@ -854,12 +823,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa2 == -1) {
-        kapa2 = KapaOpenNamedSocket ("kapa", "psphot:psfstars");
-        if (kapa2 == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
+    int myKapa = psphotKapaChannel (3);
+    if (myKapa == -1) return false;
 
     int DX = 64;
@@ -906,7 +869,7 @@
 
     psImage *psfLogFlux = (psImage *) psUnaryOp (NULL, psfMosaic, "log");
-    psphotVisualRangeImage (kapa2, psfLogFlux, "psf_mosaic",    0, -2.0, 3.0);
-    psphotVisualRangeImage (kapa2, funMosaic, "psf_analytical", 1, -10.0, 100.0);
-    psphotVisualRangeImage (kapa2, resMosaic, "psf_residual",   2, -10.0, 100.0);
+    psphotVisualRangeImage (myKapa, psfLogFlux, "psf_mosaic",    0, -2.0, 3.0);
+    psphotVisualRangeImage (myKapa, funMosaic, "psf_analytical", 1, -10.0, 100.0);
+    psphotVisualRangeImage (myKapa, resMosaic, "psf_residual",   2, -10.0, 100.0);
 
     psFree (psfMosaic);
@@ -932,12 +895,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa2 == -1) {
-        kapa2 = KapaOpenNamedSocket ("kapa", "psphot:psfstars");
-        if (kapa2 == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
+    int myKapa = psphotKapaChannel (3);
+    if (myKapa == -1) return false;
 
     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
@@ -1064,6 +1021,6 @@
     }
 
-    psphotVisualRangeImage (kapa2, outpos, "psfpos", 0, -0.05, 0.95);
-    psphotVisualRangeImage (kapa2, outsub, "psfsub", 1, -0.05, 0.95);
+    psphotVisualRangeImage (myKapa, outpos, "psfpos", 0, -0.05, 0.95);
+    psphotVisualRangeImage (myKapa, outsub, "psfsub", 1, -0.05, 0.95);
 
     // pause and wait for user input:
@@ -1092,12 +1049,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa2 == -1) {
-        kapa2 = KapaOpenNamedSocket ("kapa", "psphot:images");
-        if (kapa2 == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
+    int myKapa = psphotKapaChannel (3);
+    if (myKapa == -1) return false;
 
     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
@@ -1212,5 +1163,5 @@
     }
 
-    psphotVisualScaleImage (kapa2, outsat, "satstar", 2);
+    psphotVisualScaleImage (myKapa, outsat, "satstar", 2);
 
     // pause and wait for user input:
@@ -1345,12 +1296,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa3 == -1) {
-        kapa3 = KapaOpenNamedSocket ("kapa", "psphot:plots");
-        if (kapa3 == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
+    int myKapa = psphotKapaChannel (2);
+    if (myKapa == -1) return false;
 
     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
@@ -1359,5 +1304,5 @@
     assert (maskVal);
 
-    KapaClearPlots (kapa3);
+    KapaClearPlots (myKapa);
     // first section : mag vs CR nSigma
     section.dx = 1.0;
@@ -1367,5 +1312,5 @@
     section.name = NULL;
     psStringAppend (&section.name, "linlog");
-    KapaSetSection (kapa3, &section);
+    KapaSetSection (myKapa, &section);
     psFree (section.name);
 
@@ -1377,5 +1322,5 @@
     section.name = NULL;
     psStringAppend (&section.name, "loglog");
-    KapaSetSection (kapa3, &section);
+    KapaSetSection (myKapa, &section);
     psFree (section.name);
 
@@ -1386,5 +1331,5 @@
         if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
 
-        psphotVisualPlotRadialProfile (kapa3, source, maskVal);
+        psphotVisualPlotRadialProfile (myKapa, source, maskVal);
 
         // pause and wait for user input:
@@ -1396,5 +1341,5 @@
         }
         if (key[0] == 'e') {
-            KapaClearPlots (kapa3);
+            KapaClearPlots (myKapa);
         }
         if (key[0] == 's') {
@@ -1417,8 +1362,6 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        fprintf (stderr, "kapa not opened, skipping\n");
-        return false;
-    }
+    int myKapa = psphotKapaChannel (1);
+    if (myKapa == -1) return false;
 
     // note: this uses the Ohana allocation tools:
@@ -1493,6 +1436,6 @@
     }
 
-    KiiLoadOverlay (kapa, overlayE, NoverlayE, "red");
-    KiiLoadOverlay (kapa, overlayO, NoverlayO, "yellow");
+    KiiLoadOverlay (myKapa, overlayE, NoverlayE, "red");
+    KiiLoadOverlay (myKapa, overlayO, NoverlayO, "yellow");
     FREE (overlayE);
     FREE (overlayO);
@@ -1511,22 +1454,16 @@
 }
 
-bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources) {
-
-    int Noverlay, NOVERLAY;
+bool psphotVisualShowSourceSize_Single (int myKapa, psArray *sources, pmSourceMode mode, bool keep, float scale, char *color) {
+
+    int Noverlay;
     KiiOverlay *overlay;
 
-    if (!pmVisualIsVisual()) return true;
-
-    if (kapa == -1) {
-        fprintf (stderr, "kapa not opened, skipping\n");
-        return false;
-    }
+    psEllipseMoments emoments;
+    psEllipseAxes axes;
 
     // note: this uses the Ohana allocation tools:
+    ALLOCATE (overlay, KiiOverlay, sources->n);
+
     Noverlay = 0;
-    NOVERLAY = 100;
-    ALLOCATE (overlay, KiiOverlay, sources->n);
-
-    // mark CRs with red boxes
     for (int i = 0; i < sources->n; i++) {
 
@@ -1534,194 +1471,522 @@
         if (source == NULL) continue;
 
-        if (!(source->mode & PM_SOURCE_MODE_CR_LIMIT)) continue;
-
-        overlay[Noverlay].type = KII_OVERLAY_BOX;
-        overlay[Noverlay].x = source->peak->xf;
-        overlay[Noverlay].y = source->peak->yf;
-
-        overlay[Noverlay].dx = 4;
-        overlay[Noverlay].dy = 4;
-        overlay[Noverlay].angle = 0;
+        // if (source->type != type) continue;
+	if (mode) {
+	    if (keep) {
+		if (!(source->mode & mode)) continue;
+	    } else {
+		if (source->mode & mode) continue;
+	    }
+	}
+
+        pmMoments *moments = source->moments;
+        if (moments == NULL) continue;
+
+        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
+        overlay[Noverlay].x = moments->Mx;
+        overlay[Noverlay].y = moments->My;
+
+        emoments.x2 = moments->Mxx;
+        emoments.y2 = moments->Myy;
+        emoments.xy = moments->Mxy;
+
+        axes = psEllipseMomentsToAxes (emoments, 20.0);
+
+        overlay[Noverlay].dx = scale*2.0*axes.major;
+        overlay[Noverlay].dy = scale*2.0*axes.minor;
+        overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
         overlay[Noverlay].text = NULL;
         Noverlay ++;
-        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
-    }
-    KiiLoadOverlay (kapa, overlay, Noverlay, "red");
-
-
-    Noverlay = 0;
-    for (int i = 0; i < sources->n; i++) {
-
-        pmSource *source = sources->data[i];
-        if (source == NULL) continue;
-
-        // mark EXTs with yellow circles
-        if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue;
-
-        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
-        overlay[Noverlay].x = source->peak->xf;
-        overlay[Noverlay].y = source->peak->yf;
-
-        overlay[Noverlay].dx = 10;
-        overlay[Noverlay].dy = 10;
-        overlay[Noverlay].angle = 0;
-        overlay[Noverlay].text = NULL;
-        Noverlay ++;
-        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
-    }
-
-    KiiLoadOverlay (kapa, overlay, Noverlay, "blue");
+    }
+
+    KiiLoadOverlay (myKapa, overlay, Noverlay, color);
     FREE (overlay);
 
-    psphotVisualShowMask (kapa, readout->mask, "mask", 2);
+    return true;
+}
+
+bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources) {
+
+    // if (!pmVisualIsVisual()) return true;
+
+    int myKapa = psphotKapaChannel (1);
+    if (myKapa == -1) return false;
+
+    KiiEraseOverlay (myKapa, "red");
+    KiiEraseOverlay (myKapa, "blue");
+    KiiEraseOverlay (myKapa, "green");
+    KiiEraseOverlay (myKapa, "yellow");
+
+    psphotVisualShowSourceSize_Single (myKapa, sources, PM_SOURCE_MODE_EXT_LIMIT | PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_SATSTAR, 0, 1.0, "green");
+    psphotVisualShowSourceSize_Single (myKapa, sources, PM_SOURCE_MODE_EXT_LIMIT, 1, 1.0, "blue");
+    psphotVisualShowSourceSize_Single (myKapa, sources, PM_SOURCE_MODE_CR_LIMIT, 1, 1.0, "red");
+    psphotVisualShowSourceSize_Single (myKapa, sources, PM_SOURCE_MODE_DEFECT, 1, 2.0, "red");
+    psphotVisualShowSourceSize_Single (myKapa, sources, PM_SOURCE_MODE_SATSTAR, 1, 1.0, "yellow");
 
     // pause and wait for user input:
     // continue, save (provide name), ??
     char key[10];
-    fprintf (stdout, "CR: 4pix red BOX; EXT: 10pix blue circle\n");
+    fprintf (stdout, "red: CR; blue: EXTENDED; green: PSF-like; yellow: SATSTAR\n");
     fprintf (stdout, "[c]ontinue? ");
     if (!fgets(key, 8, stdin)) {
         psWarning("Unable to read option");
     }
-
-    return true;
-}
-
-bool psphotVisualPlotSourceSize (psArray *sources) {
-
+    return true;
+}
+
+bool psphotVisualPlotSourceSize (psMetadata *recipe, psArray *sources) {
+
+    bool status;
     Graphdata graphdata;
     KapaSection section;
 
-    if (!pmVisualIsVisual()) return true;
-
-    if (kapa3 == -1) {
-        kapa3 = KapaOpenNamedSocket ("kapa", "psphot:plots");
-        if (kapa3 == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
+    // if (!pmVisualIsVisual()) return true;
+
+    int myKapa = psphotKapaChannel (2);
+    if (myKapa == -1) return false;
+
+    KapaClearPlots (myKapa);
+    KapaInitGraph (&graphdata);
+    KapaSetFont (myKapa, "courier", 14);
+
+    // select the max psfX,Y values for the plot limits
+    float Xmin = 1000.0, Xmax = 0.0;
+    float Ymin = 1000.0, Ymax = 0.0;
+    {
+        int nRegions = psMetadataLookupS32 (&status, recipe, "PSF.CLUMP.NREGIONS");
+        for (int n = 0; n < nRegions; n++) {
+
+            char regionName[64];
+            snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
+            psMetadata *regionMD = psMetadataLookupPtr (&status, recipe, regionName);
+
+	    float psfX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
+            float psfY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
+            float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
+            float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
+
+	    float X0 = psfX - 10.0*psfdX;
+	    float X1 = psfX + 10.0*psfdX;
+	    float Y0 = psfY - 10.0*psfdY;
+	    float Y1 = psfY + 10.0*psfdY;
+
+	    if (isfinite(X0)) { Xmin = PS_MIN(Xmin, X0); }
+	    if (isfinite(X1)) { Xmax = PS_MAX(Xmax, X1); }
+	    if (isfinite(Y0)) { Ymin = PS_MIN(Ymin, Y0); }
+	    if (isfinite(Y1)) { Ymax = PS_MAX(Ymax, Y1); }
         }
     }
-
-    KapaClearPlots (kapa3);
-    KapaInitGraph (&graphdata);
-
-    // first section : mag vs CR nSigma
-    section.dx = 1.0;
-    section.dy = 0.5;
-    section.x = 0.0;
-    section.y = 0.0;
-    section.name = NULL;
-    psStringAppend (&section.name, "a1");
-    KapaSetSection (kapa3, &section);
-    psFree (section.name);
-
-    psVector *x = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
-    psVector *y = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
-
-    graphdata.xmin = +32.0;
-    graphdata.xmax = -32.0;
-    graphdata.ymin = +32.0;
-    graphdata.ymax = -32.0;
-
-    // construct the plot vectors
-    int n = 0;
+    Xmin = PS_MAX(Xmin, -0.1); 
+    Ymin = PS_MAX(Ymin, -0.1); 
+
+    // storage vectors for data to be plotted
+    psVector *xSAT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *ySAT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *mSAT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *sSAT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+
+    psVector *xPSF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *yPSF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *mPSF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *sPSF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+
+    psVector *xEXT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *yEXT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *mEXT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *sEXT = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+
+    psVector *xDEF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *yDEF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *mDEF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *sDEF = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+
+    psVector *xCR = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *yCR = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *mCR = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *sCR = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+
+    // construct the vectors
+    int nSAT = 0;
+    int nEXT = 0;
+    int nPSF = 0;
+    int nDEF = 0;
+    int nCR  = 0;
     for (int i = 0; i < sources->n; i++) {
         pmSource *source = sources->data[i];
-        if (!source) continue;
-        if (source->type != PM_SOURCE_TYPE_STAR) continue;
-        if (!isfinite (source->crNsigma)) continue;
-	if (!isfinite (source->peak->flux)) continue;
-	if (source->peak->flux < 0) continue;
-
-        x->data.F32[n] = -2.5*log10(source->peak->flux);
-        y->data.F32[n] = source->crNsigma;
-        graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
-        graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
-        graphdata.ymin = -0.5;
-        graphdata.ymax = 10.0;
-
-        n++;
-    }
-    x->n = y->n = n;
-
-    float range;
-    range = graphdata.xmax - graphdata.xmin;
-    graphdata.xmax += 0.05*range;
-    graphdata.xmin -= 0.05*range;
-
-    // XXX set the plot range to match the image
-    KapaSetLimits (kapa3, &graphdata);
-
-    KapaSetFont (kapa3, "helvetica", 14);
-    KapaBox (kapa3, &graphdata);
-    KapaSendLabel (kapa3, "Peak as Mag", KAPA_LABEL_XM);
-    KapaSendLabel (kapa3, "CR N Sigma", KAPA_LABEL_YM);
+        if (source->moments == NULL) continue;
+
+	if (source->mode & PM_SOURCE_MODE_CR_LIMIT) { 
+	    xCR->data.F32[nCR] = source->moments->Mxx;
+	    yCR->data.F32[nCR] = source->moments->Myy;
+	    mCR->data.F32[nCR] = -2.5*log10(source->moments->Sum);
+	    sCR->data.F32[nCR] = source->extNsigma;
+	    nCR++;
+	}
+	if (source->mode & PM_SOURCE_MODE_SATSTAR) { 
+	    xSAT->data.F32[nSAT] = source->moments->Mxx;
+	    ySAT->data.F32[nSAT] = source->moments->Myy;
+	    mSAT->data.F32[nSAT] = -2.5*log10(source->moments->Sum);
+	    sSAT->data.F32[nSAT] = source->extNsigma;
+	    nSAT++;
+	}
+	if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 
+	    xEXT->data.F32[nEXT] = source->moments->Mxx;
+	    yEXT->data.F32[nEXT] = source->moments->Myy;
+	    mEXT->data.F32[nEXT] = -2.5*log10(source->moments->Sum);
+	    sEXT->data.F32[nEXT] = source->extNsigma;
+	    nEXT++;
+	    continue;
+	}
+	if (source->mode & PM_SOURCE_MODE_DEFECT) { 
+	    xDEF->data.F32[nDEF] = source->moments->Mxx;
+	    yDEF->data.F32[nDEF] = source->moments->Myy;
+	    mDEF->data.F32[nDEF] = -2.5*log10(source->moments->Sum);
+	    sDEF->data.F32[nDEF] = source->extNsigma;
+	    nDEF++;
+	    continue;
+	}
+	if ((source->mode & PM_SOURCE_MODE_CR_LIMIT) || (source->mode & PM_SOURCE_MODE_SATSTAR)) {
+	    continue;
+	}
+	xPSF->data.F32[nPSF] = source->moments->Mxx;
+	yPSF->data.F32[nPSF] = source->moments->Myy;
+	mPSF->data.F32[nPSF] = -2.5*log10(source->moments->Sum);
+	sPSF->data.F32[nPSF] = source->extNsigma;
+	nPSF++;
+    }
+    xSAT->n = nSAT;
+    ySAT->n = nSAT;
+    mSAT->n = nSAT;
+    sSAT->n = nSAT;
+
+    xPSF->n = nPSF;
+    yPSF->n = nPSF;
+    mPSF->n = nPSF;
+    sPSF->n = nPSF;
+
+    xEXT->n = nEXT;
+    yEXT->n = nEXT;
+    mEXT->n = nEXT;
+    sEXT->n = nEXT;
+
+    xCR->n = nCR;
+    yCR->n = nCR;
+    mCR->n = nCR;
+    sCR->n = nCR;
+
+    xDEF->n = nDEF;
+    yDEF->n = nDEF;
+    mDEF->n = nDEF;
+    sDEF->n = nDEF;
+
+    // four sections: MxxMyy, MagMxx, MagMyy, MagSigma
+
+    // first section: MxxMyy
+    section.dx = 0.75;
+    section.dy = 0.60;
+    section.x  = 0.00;
+    section.y  = 0.00;
+    section.name = psStringCopy ("MxxMyy");
+    KapaSetSection (myKapa, &section);
+    psFree (section.name);
 
     graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 2;
+    graphdata.xmin = Xmin;
+    graphdata.ymin = Ymin;
+    graphdata.xmax = Xmax;
+    graphdata.ymax = Ymax;
+    KapaSetLimits (myKapa, &graphdata);
+
+    KapaBox (myKapa, &graphdata);
+    KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM);
+    KapaSendLabel (myKapa, "M_yy| (pixels)", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ptype = 0;
     graphdata.size = 0.5;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, n, &graphdata);
-    KapaPlotVector (kapa3, n, x->data.F32, "x");
-    KapaPlotVector (kapa3, n, y->data.F32, "y");
-
-    // second section : mag vs EXT nSigma
-    section.dx = 1.0;
-    section.dy = 0.5;
-    section.x = 0.0;
-    section.y = 0.5;
-    section.name = NULL;
-    psStringAppend (&section.name, "a2");
-    KapaSetSection (kapa3, &section);
+    KapaPrepPlot   (myKapa, nPSF, &graphdata);
+    KapaPlotVector (myKapa, nPSF, xPSF->data.F32, "x");
+    KapaPlotVector (myKapa, nPSF, yPSF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nEXT, &graphdata);
+    KapaPlotVector (myKapa, nEXT, xEXT->data.F32, "x");
+    KapaPlotVector (myKapa, nEXT, yEXT->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nDEF, &graphdata);
+    KapaPlotVector (myKapa, nDEF, xDEF->data.F32, "x");
+    KapaPlotVector (myKapa, nDEF, yDEF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nCR, &graphdata);
+    KapaPlotVector (myKapa, nCR, xCR->data.F32, "x");
+    KapaPlotVector (myKapa, nCR, yCR->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nSAT, &graphdata);
+    KapaPlotVector (myKapa, nSAT, xSAT->data.F32, "x");
+    KapaPlotVector (myKapa, nSAT, ySAT->data.F32, "y");
+
+    // second section: MagMyy
+    section.dx = 0.75;
+    section.dy = 0.20;
+    section.x  = 0.00;
+    section.y  = 0.80;
+    section.name = psStringCopy ("MagMyy");
+    KapaSetSection (myKapa, &section);
     psFree (section.name);
 
-    graphdata.xmin = +32.0;
-    graphdata.xmax = -32.0;
-    graphdata.ymin = +32.0;
-    graphdata.ymax = -32.0;
-
-    // construct the plot vectors
-    n = 0;
-    for (int i = 0; i < sources->n; i++) {
-        pmSource *source = sources->data[i];
-        if (!source) continue;
-        if (source->type != PM_SOURCE_TYPE_STAR) continue;
-        if (!isfinite (source->extNsigma)) continue;
-	if (!isfinite (source->peak->flux)) continue;
-	if (source->peak->flux < 0) continue;
-
-        x->data.F32[n] = -2.5*log10(source->peak->flux);
-        y->data.F32[n] = source->extNsigma;
-        graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
-        graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
-        graphdata.ymin = -0.5;
-        graphdata.ymax = 10.0;
-
-        n++;
-    }
-    x->n = y->n = n;
-
-    range = graphdata.xmax - graphdata.xmin;
-    graphdata.xmax += 0.05*range;
-    graphdata.xmin -= 0.05*range;
-
-    // XXX set the plot range to match the image
-    KapaSetLimits (kapa3, &graphdata);
-
-    KapaSetFont (kapa3, "helvetica", 14);
-    KapaBox (kapa3, &graphdata);
-    KapaSendLabel (kapa3, "EXT N Sigma", KAPA_LABEL_YM);
-
     graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 2;
+    graphdata.xmin = -17.1;
+    graphdata.xmax =  -7.9;
+    graphdata.ymin = Ymin;
+    graphdata.ymax = Ymax;
+    KapaSetLimits (myKapa, &graphdata);
+
+    strcpy (graphdata.labels, "0210");
+    KapaBox (myKapa, &graphdata);
+    KapaSendLabel (myKapa, "inst mag", KAPA_LABEL_XP);
+    KapaSendLabel (myKapa, "M_yy| (pixels)", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ptype = 0;
     graphdata.size = 0.5;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, n, &graphdata);
-    KapaPlotVector (kapa3, n, x->data.F32, "x");
-    KapaPlotVector (kapa3, n, y->data.F32, "y");
-
-    psFree (x);
-    psFree (y);
+    KapaPrepPlot   (myKapa, nPSF, &graphdata);
+    KapaPlotVector (myKapa, nPSF, mPSF->data.F32, "x");
+    KapaPlotVector (myKapa, nPSF, yPSF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nEXT, &graphdata);
+    KapaPlotVector (myKapa, nEXT, mEXT->data.F32, "x");
+    KapaPlotVector (myKapa, nEXT, yEXT->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nDEF, &graphdata);
+    KapaPlotVector (myKapa, nDEF, mDEF->data.F32, "x");
+    KapaPlotVector (myKapa, nDEF, yDEF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nCR, &graphdata);
+    KapaPlotVector (myKapa, nCR, mCR->data.F32, "x");
+    KapaPlotVector (myKapa, nCR, yCR->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nSAT, &graphdata);
+    KapaPlotVector (myKapa, nSAT, mSAT->data.F32, "x");
+    KapaPlotVector (myKapa, nSAT, ySAT->data.F32, "y");
+
+    // third section: MagMxx
+    section.dx = 0.25;
+    section.dy = 0.60;
+    section.x  = 0.80;
+    section.y  = 0.00;
+    section.name = psStringCopy ("MagMxx");
+    KapaSetSection (myKapa, &section);
+    psFree (section.name);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.xmin = Xmin;
+    graphdata.xmax = Xmax;
+    graphdata.ymin =  -7.9;
+    graphdata.ymax = -17.1;
+    KapaSetLimits (myKapa, &graphdata);
+
+    strcpy (graphdata.labels, "2001");
+    KapaBox (myKapa, &graphdata);
+    KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM);
+    KapaSendLabel (myKapa, "inst mag", KAPA_LABEL_YP);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nPSF, &graphdata);
+    KapaPlotVector (myKapa, nPSF, xPSF->data.F32, "x");
+    KapaPlotVector (myKapa, nPSF, mPSF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nEXT, &graphdata);
+    KapaPlotVector (myKapa, nEXT, xEXT->data.F32, "x");
+    KapaPlotVector (myKapa, nEXT, mEXT->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nDEF, &graphdata);
+    KapaPlotVector (myKapa, nDEF, xDEF->data.F32, "x");
+    KapaPlotVector (myKapa, nDEF, mDEF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nCR, &graphdata);
+    KapaPlotVector (myKapa, nCR, xCR->data.F32, "x");
+    KapaPlotVector (myKapa, nCR, mCR->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nSAT, &graphdata);
+    KapaPlotVector (myKapa, nSAT, xSAT->data.F32, "x");
+    KapaPlotVector (myKapa, nSAT, mSAT->data.F32, "y");
+
+    // fourth section: MagSigma
+    section.dx = 0.75;
+    section.dy = 0.15;
+    section.x  = 0.00;
+    section.y  = 0.65;
+    section.name = psStringCopy ("MagSigma");
+    KapaSetSection (myKapa, &section);
+    psFree (section.name);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.xmax =  -7.9;
+    graphdata.xmin = -17.1;
+    graphdata.ymin = -20.1;
+    graphdata.ymax = +20.1;
+    KapaSetLimits (myKapa, &graphdata);
+
+    strcpy (graphdata.labels, "0100");
+    KapaBox (myKapa, &graphdata);
+    // KapaSendLabel (myKapa, "inst mag", KAPA_LABEL_XM);
+    KapaSendLabel (myKapa, "EXT&ss&c", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nPSF, &graphdata);
+    KapaPlotVector (myKapa, nPSF, mPSF->data.F32, "x");
+    KapaPlotVector (myKapa, nPSF, sPSF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nEXT, &graphdata);
+    KapaPlotVector (myKapa, nEXT, mEXT->data.F32, "x");
+    KapaPlotVector (myKapa, nEXT, sEXT->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 0;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nDEF, &graphdata);
+    KapaPlotVector (myKapa, nDEF, mDEF->data.F32, "x");
+    KapaPlotVector (myKapa, nDEF, sDEF->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nCR, &graphdata);
+    KapaPlotVector (myKapa, nCR, mCR->data.F32, "x");
+    KapaPlotVector (myKapa, nCR, sCR->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("blue");
+    graphdata.ptype = 7;
+    graphdata.size = 1.0;
+    graphdata.style = 2;
+    KapaPrepPlot   (myKapa, nSAT, &graphdata);
+    KapaPlotVector (myKapa, nSAT, mSAT->data.F32, "x");
+    KapaPlotVector (myKapa, nSAT, sSAT->data.F32, "y");
+
+    // draw N circles to outline the clumps
+    {
+        KapaSelectSection (myKapa, "MxxMyy");
+
+        // draw a circle centered on psfX,Y with size of the psf limit
+        psVector *xLimit  = psVectorAlloc (120, PS_TYPE_F32);
+        psVector *yLimit  = psVectorAlloc (120, PS_TYPE_F32);
+
+        int nRegions = psMetadataLookupS32 (&status, recipe, "PSF.CLUMP.NREGIONS");
+        float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA");
+
+        graphdata.color = KapaColorByName ("blue");
+        graphdata.style = 0;
+
+	graphdata.xmin = Xmin;
+	graphdata.ymin = Ymin;
+	graphdata.xmax = Xmax;
+	graphdata.ymax = Ymax;
+	KapaSetLimits (myKapa, &graphdata);
+
+        for (int n = 0; n < nRegions; n++) {
+
+            char regionName[64];
+            snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", n);
+            psMetadata *regionMD = psMetadataLookupPtr (&status, recipe, regionName);
+
+            float psfX  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X");
+            float psfY  = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y");
+            float psfdX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX");
+            float psfdY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY");
+            float Rx = psfdX * PSF_CLUMP_NSIGMA;
+            float Ry = psfdY * PSF_CLUMP_NSIGMA;
+
+            for (int i = 0; i < xLimit->n; i++) {
+                xLimit->data.F32[i] = Rx*cos(i*2.0*M_PI/120.0) + psfX;
+                yLimit->data.F32[i] = Ry*sin(i*2.0*M_PI/120.0) + psfY;
+            }
+            KapaPrepPlot (myKapa, xLimit->n, &graphdata);
+            KapaPlotVector (myKapa, xLimit->n, xLimit->data.F32, "x");
+            KapaPlotVector (myKapa, yLimit->n, yLimit->data.F32, "y");
+        }
+        psFree (xLimit);
+        psFree (yLimit);
+    }
+
+    psFree (xSAT);
+    psFree (ySAT);
+    psFree (mSAT);
+
+    psFree (xEXT);
+    psFree (yEXT);
+    psFree (mEXT);
+
+    psFree (xPSF);
+    psFree (yPSF);
+    psFree (mPSF);
+
+    psFree (xDEF);
+    psFree (yDEF);
+    psFree (mDEF);
+
+    psFree (xCR);
+    psFree (yCR);
+    psFree (mCR);
 
     // pause and wait for user input:
@@ -1739,14 +2004,8 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa == -1) {
-        kapa = KapaOpenNamedSocket ("kapa", "psphot:images");
-        if (kapa == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
-
-    psphotVisualScaleImage (kapa, readout->image, "resid", 1);
+    int myKapa = psphotKapaChannel (1);
+    if (myKapa == -1) return false;
+
+    psphotVisualScaleImage (myKapa, readout->image, "resid", 1);
 
     // pause and wait for user input:
@@ -1766,14 +2025,8 @@
     if (!pmVisualIsVisual()) return true;
 
-    if (kapa3 == -1) {
-        kapa3 = KapaOpenNamedSocket ("kapa", "psphot:plots");
-        if (kapa3 == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
-
-    KapaClearPlots (kapa3);
+    int myKapa = psphotKapaChannel (2);
+    if (myKapa == -1) return false;
+
+    KapaClearPlots (myKapa);
     KapaInitGraph (&graphdata);
 
@@ -1815,10 +2068,10 @@
 
     // XXX set the plot range to match the image
-    KapaSetLimits (kapa3, &graphdata);
-
-    KapaSetFont (kapa3, "helvetica", 14);
-    KapaBox (kapa3, &graphdata);
-    KapaSendLabel (kapa3, "PSF Mag", KAPA_LABEL_XM);
-    KapaSendLabel (kapa3, "Ap Mag - PSF Mag", KAPA_LABEL_YM);
+    KapaSetLimits (myKapa, &graphdata);
+
+    KapaSetFont (myKapa, "helvetica", 14);
+    KapaBox (myKapa, &graphdata);
+    KapaSendLabel (myKapa, "PSF Mag", KAPA_LABEL_XM);
+    KapaSendLabel (myKapa, "Ap Mag - PSF Mag", KAPA_LABEL_YM);
 
     graphdata.color = KapaColorByName ("black");
@@ -1826,7 +2079,7 @@
     graphdata.size = 0.5;
     graphdata.style = 2;
-    KapaPrepPlot (kapa3, n, &graphdata);
-    KapaPlotVector (kapa3, n, x->data.F32, "x");
-    KapaPlotVector (kapa3, n, y->data.F32, "y");
+    KapaPrepPlot (myKapa, n, &graphdata);
+    KapaPlotVector (myKapa, n, x->data.F32, "x");
+    KapaPlotVector (myKapa, n, y->data.F32, "y");
 
     psFree (x);
@@ -1850,4 +2103,7 @@
 
     if (!pmVisualIsVisual()) return true;
+
+    int kapa = psphotKapaChannel (3);
+    if (kapa == -1) return false;
 
     if (kapa == -1) {
@@ -1896,2 +2152,259 @@
 
 # endif
+
+# if (0)
+    // *** make a histogram of the source counts in the x and y directions
+    psHistogram *nX = psHistogramAlloc (graphdata.xmin, graphdata.xmax, 50.0);
+    psHistogram *nY = psHistogramAlloc (graphdata.ymin, graphdata.ymax, 50.0);
+    psVectorHistogram (nX, xFaint, NULL, NULL, 0);
+    psVectorHistogram (nY, yFaint, NULL, NULL, 0);
+    psVector *dX = psVectorAlloc (nX->nums->n, PS_TYPE_F32);
+    psVector *vX = psVectorAlloc (nX->nums->n, PS_TYPE_F32);
+    psVector *dY = psVectorAlloc (nY->nums->n, PS_TYPE_F32);
+    psVector *vY = psVectorAlloc (nY->nums->n, PS_TYPE_F32);
+    for (int i = 0; i < nX->nums->n; i++) {
+        dX->data.F32[i] = nX->nums->data.S32[i];
+        vX->data.F32[i] = 0.5*(nX->bounds->data.F32[i] + nX->bounds->data.F32[i+1]);
+    }
+    for (int i = 0; i < nY->nums->n; i++) {
+        dY->data.F32[i] = nY->nums->data.S32[i];
+        vY->data.F32[i] = 0.5*(nY->bounds->data.F32[i] + nY->bounds->data.F32[i+1]);
+    }
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ptype = 0;
+    graphdata.size = 0.0;
+    graphdata.style = 0;
+    KapaPrepPlot (myKapa, dX->n, &graphdata);
+    KapaPlotVector (myKapa, dX->n, dX->data.F32, "x");
+    KapaPlotVector (myKapa, vX->n, vX->data.F32, "y");
+
+    psFree (nX);
+    psFree (dX);
+    psFree (vX);
+
+    psFree (nY);
+    psFree (dY);
+    psFree (vY);
+
+
+bool psphotVisualShowSourceSize_old (pmReadout *readout, psArray *sources) {
+
+    int Noverlay, NOVERLAY;
+    KiiOverlay *overlay;
+
+    if (!pmVisualIsVisual()) return true;
+
+    if (kapa == -1) {
+        fprintf (stderr, "kapa not opened, skipping\n");
+        return false;
+    }
+
+    // note: this uses the Ohana allocation tools:
+    Noverlay = 0;
+    NOVERLAY = 100;
+    ALLOCATE (overlay, KiiOverlay, sources->n);
+
+    // mark CRs with red boxes
+    for (int i = 0; i < sources->n; i++) {
+
+        pmSource *source = sources->data[i];
+        if (source == NULL) continue;
+
+        if (!(source->mode & PM_SOURCE_MODE_CR_LIMIT)) continue;
+
+        overlay[Noverlay].type = KII_OVERLAY_BOX;
+        overlay[Noverlay].x = source->peak->xf;
+        overlay[Noverlay].y = source->peak->yf;
+
+        overlay[Noverlay].dx = 4;
+        overlay[Noverlay].dy = 4;
+        overlay[Noverlay].angle = 0;
+        overlay[Noverlay].text = NULL;
+        Noverlay ++;
+        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
+    }
+    KiiLoadOverlay (kapa, overlay, Noverlay, "red");
+
+
+    Noverlay = 0;
+    for (int i = 0; i < sources->n; i++) {
+
+        pmSource *source = sources->data[i];
+        if (source == NULL) continue;
+
+        // mark EXTs with yellow circles
+        if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue;
+
+        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
+        overlay[Noverlay].x = source->peak->xf;
+        overlay[Noverlay].y = source->peak->yf;
+
+        overlay[Noverlay].dx = 10;
+        overlay[Noverlay].dy = 10;
+        overlay[Noverlay].angle = 0;
+        overlay[Noverlay].text = NULL;
+        Noverlay ++;
+        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
+    }
+
+    KiiLoadOverlay (kapa, overlay, Noverlay, "blue");
+    FREE (overlay);
+
+    psphotVisualShowMask (kapa, readout->mask, "mask", 2);
+
+    // pause and wait for user input:
+    // continue, save (provide name), ??
+    char key[10];
+    fprintf (stdout, "CR: 4pix red BOX; EXT: 10pix blue circle\n");
+    fprintf (stdout, "[c]ontinue? ");
+    if (!fgets(key, 8, stdin)) {
+        psWarning("Unable to read option");
+    }
+
+    return true;
+}
+
+bool psphotVisualPlotSourceSize_old (psArray *sources) {
+
+    Graphdata graphdata;
+    KapaSection section;
+
+    if (!pmVisualIsVisual()) return true;
+
+    int kapa = psphotKapaChannel (2);
+    if (kapa == -1) return false;
+
+    KapaClearPlots (kapa3);
+    KapaInitGraph (&graphdata);
+
+    // first section : mag vs CR nSigma
+    section.dx = 1.0;
+    section.dy = 0.5;
+    section.x = 0.0;
+    section.y = 0.0;
+    section.name = NULL;
+    psStringAppend (&section.name, "a1");
+    KapaSetSection (kapa3, &section);
+    psFree (section.name);
+
+    psVector *x = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+    psVector *y = psVectorAllocEmpty (sources->n, PS_TYPE_F32);
+
+    graphdata.xmin = +32.0;
+    graphdata.xmax = -32.0;
+    graphdata.ymin = +32.0;
+    graphdata.ymax = -32.0;
+
+    // construct the plot vectors
+    int n = 0;
+    for (int i = 0; i < sources->n; i++) {
+        pmSource *source = sources->data[i];
+        if (!source) continue;
+        if (source->type != PM_SOURCE_TYPE_STAR) continue;
+        if (!isfinite (source->crNsigma)) continue;
+	if (!isfinite (source->peak->flux)) continue;
+	if (source->peak->flux < 0) continue;
+
+        x->data.F32[n] = -2.5*log10(source->peak->flux);
+        y->data.F32[n] = source->crNsigma;
+        graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
+        graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
+        graphdata.ymin = -0.5;
+        graphdata.ymax = 10.0;
+
+        n++;
+    }
+    x->n = y->n = n;
+
+    float range;
+    range = graphdata.xmax - graphdata.xmin;
+    graphdata.xmax += 0.05*range;
+    graphdata.xmin -= 0.05*range;
+
+    // XXX set the plot range to match the image
+    KapaSetLimits (kapa3, &graphdata);
+
+    KapaSetFont (kapa3, "helvetica", 14);
+    KapaBox (kapa3, &graphdata);
+    KapaSendLabel (kapa3, "Peak as Mag", KAPA_LABEL_XM);
+    KapaSendLabel (kapa3, "CR N Sigma", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ptype = 2;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot (kapa3, n, &graphdata);
+    KapaPlotVector (kapa3, n, x->data.F32, "x");
+    KapaPlotVector (kapa3, n, y->data.F32, "y");
+
+    // second section : mag vs EXT nSigma
+    section.dx = 1.0;
+    section.dy = 0.5;
+    section.x = 0.0;
+    section.y = 0.5;
+    section.name = NULL;
+    psStringAppend (&section.name, "a2");
+    KapaSetSection (kapa3, &section);
+    psFree (section.name);
+
+    graphdata.xmin = +32.0;
+    graphdata.xmax = -32.0;
+    graphdata.ymin = +32.0;
+    graphdata.ymax = -32.0;
+
+    // construct the plot vectors
+    n = 0;
+    for (int i = 0; i < sources->n; i++) {
+        pmSource *source = sources->data[i];
+        if (!source) continue;
+        if (source->type != PM_SOURCE_TYPE_STAR) continue;
+        if (!isfinite (source->extNsigma)) continue;
+	if (!isfinite (source->peak->flux)) continue;
+	if (source->peak->flux < 0) continue;
+
+        x->data.F32[n] = -2.5*log10(source->peak->flux);
+        y->data.F32[n] = source->extNsigma;
+        graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
+        graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
+        graphdata.ymin = -0.5;
+        graphdata.ymax = 10.0;
+
+        n++;
+    }
+    x->n = y->n = n;
+
+    range = graphdata.xmax - graphdata.xmin;
+    graphdata.xmax += 0.05*range;
+    graphdata.xmin -= 0.05*range;
+
+    // XXX set the plot range to match the image
+    KapaSetLimits (kapa3, &graphdata);
+
+    KapaSetFont (kapa3, "helvetica", 14);
+    KapaBox (kapa3, &graphdata);
+    KapaSendLabel (kapa3, "EXT N Sigma", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ptype = 2;
+    graphdata.size = 0.5;
+    graphdata.style = 2;
+    KapaPrepPlot (kapa3, n, &graphdata);
+    KapaPlotVector (kapa3, n, x->data.F32, "x");
+    KapaPlotVector (kapa3, n, y->data.F32, "y");
+
+    psFree (x);
+    psFree (y);
+
+    // pause and wait for user input:
+    // continue, save (provide name), ??
+    char key[10];
+    fprintf (stdout, "[c]ontinue? ");
+    if (!fgets(key, 8, stdin)) {
+        psWarning("Unable to read option");
+    }
+    return true;
+}
+
+# endif
+
