Index: trunk/psphot/src/psphot.h
===================================================================
--- trunk/psphot/src/psphot.h	(revision 19869)
+++ trunk/psphot/src/psphot.h	(revision 19880)
@@ -141,9 +141,13 @@
 bool psphotVisualShowFootprints (pmConfig *config, const pmFPAview *view, pmDetections *detections);
 bool psphotVisualShowMoments (pmConfig *config, const pmFPAview *view, psArray *sources);
+bool psphotVisualPlotMoments (pmConfig *config, const pmFPAview *view, psArray *sources);
 bool psphotVisualShowRoughClass (pmConfig *config, const pmFPAview *view, psArray *sources);
 bool psphotVisualShowPSFStars (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources);
 bool psphotVisualShowSatStars (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources);
-bool psphotVisualShowLinearFit (pmConfig *config, pmReadout *readout);
 bool psphotVisualShowPSFModel (pmConfig *config, pmReadout *readout, pmPSF *psf);
+bool psphotVisualShowFlags (pmConfig *config, const pmFPAview *view, psArray *sources);
+bool psphotVisualShowSourceSize (pmConfig *config, const pmFPAview *view, psArray *sources);
+bool psphotVisualShowResidualImage (pmConfig *config, pmReadout *readout);
+bool psphotVisualPlotApResid (pmConfig *config, psArray *sources);
 
 // structures & functions to support psf-convolved model fitting
Index: trunk/psphot/src/psphotReadout.c
===================================================================
--- trunk/psphot/src/psphotReadout.c	(revision 19869)
+++ trunk/psphot/src/psphotReadout.c	(revision 19880)
@@ -69,14 +69,7 @@
     }
  
-    // display the backsub and backgnd images
+    // display the peaks and footprints
     psphotVisualShowPeaks (config, view, detections);
     psphotVisualShowFootprints (config, view, detections);
-
-    // XXX test write out the footprint image
-    if (0) {
-	psImage *footprintImage = pmSetFootprintArrayIDs (detections->footprints, true);
-	psphotSaveImage (NULL, footprintImage, "footprints.1.fits");
-	psFree (footprintImage);
-    }
 
     // construct sources and measure basic stats
@@ -109,4 +102,5 @@
 
     psphotVisualShowRoughClass (config, view, sources);
+    psphotVisualShowFlags (config, view, sources);
 
     // if we were not supplied a PSF, choose one here
@@ -173,25 +167,6 @@
     psphotVisualShowPSFStars (config, view, psf, sources);
     psphotVisualShowSatStars (config, view, psf, sources);
-    psphotVisualShowLinearFit (config, readout);
-
-    if (0) {
-        FILE *out = fopen ("out.pass1.dat", "w");
-
-        for (int i = 0; i < sources->n; i++) {
-            pmSource *source = sources->data[i];
-            if (!source) continue;
-            pmPeak *peak = source->peak;
-            if (!peak) continue;
-            pmModel *model = source->modelPSF;
-            if (!model) continue;
-            if (!model->params) continue;
-
-            fprintf (out, "%d %f %f  %f %f  %f %f\n",
-                     i, peak->xf, peak->yf, peak->flux, peak->SN,
-                     model->params->data.F32[PM_PAR_I0],
-                     model->dparams->data.F32[PM_PAR_I0]);
-        }
-        fclose (out);
-    }
+    psphotVisualShowResidualImage (config, readout);
+    psphotVisualShowFlags (config, view, sources);
 
     // identify CRs and extended sources
@@ -201,10 +176,11 @@
     }
 
-    // XXX psphotVisualShowSourceSize (config, view, sources);
+    psphotVisualShowSourceSize (config, view, sources);
 
     // non-linear PSF and EXT fit to brighter sources
     psphotBlendFit (readout, sources, recipe, psf);
 
-    // XXX psphotVisualShowNonLinearFit (config, view, sources);
+    psphotVisualShowResidualImage (config, readout);
+    psphotVisualShowFlags (config, view, sources);
 
     // replace all sources
@@ -213,4 +189,7 @@
     // linear fit to include all sources
     psphotFitSourcesLinear (readout, sources, recipe, psf, TRUE);
+
+    psphotVisualShowResidualImage (config, readout);
+    psphotVisualShowFlags (config, view, sources);
 
     // if we only do one pass, skip to extended source analysis
@@ -231,12 +210,10 @@
     detections = psphotFindDetections (detections, readout, recipe);
 
-    // XXX test write out the footprint image
-    if (0) {
-        psImage *footprintImage = pmSetFootprintArrayIDs (detections->footprints, true);
-        psphotSaveImage (NULL, footprintImage, "footprints.2.fits");
-        psFree (footprintImage);
-    }
     // remove noise for subtracted objects (ie, return to normal noise level)
     psphotSubNoise (readout, sources, recipe);
+
+    // display the new peaks and footprints
+    psphotVisualShowPeaks (config, view, detections);
+    psphotVisualShowFootprints (config, view, detections);
 
     // define new sources based on only the new peaks
@@ -249,4 +226,7 @@
     }
 
+    psphotVisualShowRoughClass (config, view, sources);
+    psphotVisualShowFlags (config, view, sources);
+
     // create full input models
     psphotGuessModels (readout, newSources, recipe, psf);
@@ -262,23 +242,6 @@
     psphotFitSourcesLinear (readout, sources, recipe, psf, TRUE);
 
-    if (0) {
-        FILE *out = fopen ("out.pass2.dat", "w");
-
-        for (int i = 0; i < sources->n; i++) {
-            pmSource *source = sources->data[i];
-            if (!source) continue;
-            pmPeak *peak = source->peak;
-            if (!peak) continue;
-            pmModel *model = source->modelPSF;
-            if (!model) continue;
-            if (!model->params) continue;
-
-            fprintf (out, "%d %f %f  %f %f  %f %f\n",
-                     i, peak->xf, peak->yf, peak->flux, peak->SN,
-                     model->params->data.F32[PM_PAR_I0],
-                     model->dparams->data.F32[PM_PAR_I0]);
-        }
-        fclose (out);
-    }
+    psphotVisualShowResidualImage (config, readout);
+    psphotVisualShowFlags (config, view, sources);
 
 pass1finish:
@@ -286,8 +249,6 @@
     // measure source size for the remaining sources
     psphotSourceSize (config, readout, sources, recipe, 0);
-    if (0) {
-        psphotSaveImage (NULL, readout->mask, "mask.fits");
-    }
-	
+    psphotVisualShowSourceSize (config, view, sources);
+
     psphotExtendedSourceAnalysis (readout, sources, recipe);
 
@@ -305,4 +266,6 @@
     }
 
+    psphotVisualPlotApResid (config, sources);
+
     // calculate source magnitudes
     pmReadout *background = psphotSelectBackground (config, view, false);
Index: trunk/psphot/src/psphotVisual.c
===================================================================
--- trunk/psphot/src/psphotVisual.c	(revision 19869)
+++ trunk/psphot/src/psphotVisual.c	(revision 19880)
@@ -399,10 +399,10 @@
 
 	overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
-	overlay[Noverlay].x = moments->x;
-	overlay[Noverlay].y = moments->y;
-
-	emoments.x2 = moments->Sx;
-	emoments.y2 = moments->Sy;
-	emoments.xy = moments->Sxy;
+	overlay[Noverlay].x = moments->Mx;
+	overlay[Noverlay].y = moments->My;
+
+	emoments.x2 = moments->Mxx;
+	emoments.xy = moments->Mxy;
+	emoments.y2 = moments->Myy;
 
 	axes = psEllipseMomentsToAxes (emoments, 20.0);
@@ -410,5 +410,5 @@
 	overlay[Noverlay].dx = 2.0*axes.major;
 	overlay[Noverlay].dy = 2.0*axes.minor;
-	overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
+	overlay[Noverlay].angle = -axes.theta * PS_DEG_RAD;  // XXXXXXXX the axes angle is negative to display of object on kapa
 	overlay[Noverlay].text = NULL;
 	Noverlay ++;
@@ -488,6 +488,6 @@
             continue;
 
-        xFaint->data.F32[nF] = source->moments->Sx;
-        yFaint->data.F32[nF] = source->moments->Sy;
+        xFaint->data.F32[nF] = source->moments->Mxx;
+        yFaint->data.F32[nF] = source->moments->Myy;
         nF++;
 
@@ -496,6 +496,6 @@
             continue;
 
-        xBright->data.F32[nB] = source->moments->Sx;
-        yBright->data.F32[nB] = source->moments->Sy;
+        xBright->data.F32[nB] = source->moments->Mxx;
+        yBright->data.F32[nB] = source->moments->Myy;
         nB++;
     }
@@ -613,10 +613,10 @@
 
 	overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
-	overlay[Noverlay].x = moments->x;
-	overlay[Noverlay].y = moments->y;
-
-	emoments.x2 = moments->Sx;
-	emoments.y2 = moments->Sy;
-	emoments.xy = moments->Sxy;
+	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);
@@ -624,5 +624,5 @@
 	overlay[Noverlay].dx = 2.0*axes.major;
 	overlay[Noverlay].dy = 2.0*axes.minor;
-	overlay[Noverlay].angle = axes.theta * PS_DEG_RAD;
+	overlay[Noverlay].angle = -axes.theta * PS_DEG_RAD;
 	overlay[Noverlay].text = NULL;
 	Noverlay ++;
@@ -1014,4 +1014,5 @@
 	    // XXX should we measure this for the analytical model only or the full model?
 	    pmModelAddWithOffset (psfMosaic, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_CENTER, 0, -x*DX, -y*DY);
+	    psFree (model);
 	}
     }
@@ -1042,15 +1043,198 @@
     psphotVisualRangeImage (kapa2, psfLogFlux, "psf_mosaic", 1, -2.0, 3.0);
 
-    // 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;
-}
-
-bool psphotVisualShowLinearFit (pmConfig *config, pmReadout *readout) {
+    psFree (psfMosaic);
+    psFree (psfLogFlux);
+
+    // 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;
+}
+
+bool psphotVisualShowFlags (pmConfig *config, const pmFPAview *view, psArray *sources) {
+
+    int NoverlayE, NOVERLAYE;
+    int NoverlayO, NOVERLAYO;
+    KiiOverlay *overlayE, *overlayO;
+  
+    psEllipseMoments emoments;
+    psEllipseAxes axes;
+
+    if (!isVisual) return true;
+
+    if (kapa == -1) {
+	fprintf (stderr, "kapa not opened, skipping\n");
+	return false;
+    }
+
+    // note: this uses the Ohana allocation tools:
+    NoverlayE = 0;
+    NOVERLAYE = 100;
+    ALLOCATE (overlayE, KiiOverlay, sources->n);
+
+    NoverlayO = 0;
+    NOVERLAYO = 100;
+    ALLOCATE (overlayO, KiiOverlay, sources->n);
+
+    for (int i = 0; i < sources->n; i++) {
+
+	float Xo, Yo, Rmaj, Rmin, cs, sn;
+
+	pmSource *source = sources->data[i];
+	if (source == NULL) continue;
+
+	pmMoments *moments = source->moments;
+	if (0) { 
+	    emoments.x2 = moments->Mxx;
+	    emoments.y2 = moments->Myy;
+	    emoments.xy = moments->Mxy;
+	    Xo = moments->Mx;
+	    Yo = moments->My;
+
+	    axes = psEllipseMomentsToAxes (emoments, 20.0);
+	    Rmaj = 2.0*axes.major;
+	    Rmin = 2.0*axes.minor;
+	    cs = cos(axes.theta);
+	    sn = sin(axes.theta);
+	} else {
+	    Rmaj = Rmin = 5.0;
+	    cs = 1.0;
+	    sn = 0.0;
+	    Xo = source->peak->xf;
+	    Yo = source->peak->yf;
+	}
+
+	unsigned short int flagMask = 0x01;
+	for (int j = 0; j < 8; j++) {
+	    if (source->mode & flagMask) {
+		overlayE[NoverlayE].type = KII_OVERLAY_LINE;
+		overlayE[NoverlayE].x = Xo;
+		overlayE[NoverlayE].y = Yo;
+
+		float phi = j*M_PI/4.0;
+		overlayE[NoverlayE].dx = +Rmaj*cos(phi)*cs - Rmin*sin(phi)*sn;
+		overlayE[NoverlayE].dy = +Rmaj*cos(phi)*sn + Rmin*sin(phi)*cs;
+		overlayE[NoverlayE].angle = 0;
+		overlayE[NoverlayE].text = NULL;
+		NoverlayE ++;
+		CHECK_REALLOCATE (overlayE, KiiOverlay, NOVERLAYE, NoverlayE, 100);
+	    }
+	    flagMask <<= 1;
+
+	    if (source->mode & flagMask) {
+		overlayO[NoverlayO].type = KII_OVERLAY_LINE;
+		overlayO[NoverlayO].x = Xo + 1;
+		overlayO[NoverlayO].y = Yo;
+
+		float phi = j*M_PI/4.0;
+		overlayO[NoverlayO].dx = +Rmaj*cos(phi)*cs - Rmin*sin(phi)*sn;
+		overlayO[NoverlayO].dy = +Rmaj*cos(phi)*sn + Rmin*sin(phi)*cs;
+		overlayO[NoverlayO].angle = 0;
+		overlayO[NoverlayO].text = NULL;
+		NoverlayO ++;
+		CHECK_REALLOCATE (overlayO, KiiOverlay, NOVERLAYO, NoverlayO, 100);
+	    }
+	    flagMask <<= 1;
+	}
+    }
+
+    KiiLoadOverlay (kapa, overlayE, NoverlayE, "red");
+    KiiLoadOverlay (kapa, overlayO, NoverlayO, "yellow");
+    FREE (overlayE);
+    FREE (overlayO);
+
+    // pause and wait for user input:
+    // continue, save (provide name), ??
+    char key[10];
+    fprintf (stdout, "even bits (0x0001, 0x0004, ... : red\n");
+    fprintf (stdout, "odd bits (0x0002, 0x0008, ... : yellow\n");
+    fprintf (stdout, "[c]ontinue? ");
+    if (!fgets(key, 8, stdin)) {
+	psWarning("Unable to read option");
+    }
+
+    return true;
+}
+
+bool psphotVisualShowSourceSize (pmConfig *config, const pmFPAview *view, psArray *sources) {
+
+    int Noverlay, NOVERLAY;
+    KiiOverlay *overlay;
+
+    if (!isVisual) 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, "yellow");
+    FREE (overlay);
+
+    // 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 psphotVisualShowResidualImage (pmConfig *config, pmReadout *readout) {
 
     if (!isVisual) return true;
@@ -1065,5 +1249,96 @@
     }  
 
-    psphotVisualScaleImage (kapa, readout->image, "lin_resid", 1);
+    psphotVisualScaleImage (kapa, readout->image, "resid", 1);
+
+    // 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;
+}
+
+bool psphotVisualPlotApResid (pmConfig *config, psArray *sources) {
+
+    bool status;
+    Graphdata graphdata;
+
+    if (!isVisual) return true;
+
+    if (kapa3 == -1) {
+        kapa3 = KapaOpenNamedSocket ("kapa", "psphot:plots");
+	if (kapa3 == -1) {
+	    fprintf (stderr, "failure to open kapa; visual mode disabled\n");
+	    isVisual = false;
+	    return false;
+	}
+    }  
+
+    // select the current recipe
+    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    if (!recipe) {
+	fprintf (stderr, "missing recipe, skipping moments plot\n");
+        return false;
+    }
+
+    KapaClearPlots (kapa3);
+    KapaInitGraph (&graphdata);
+
+    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->apMag)) continue;
+	if (!isfinite (source->psfMag)) continue;
+
+        x->data.F32[n] = source->psfMag;
+        y->data.F32[n] = source->apMag - source->psfMag;
+        graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]);
+        graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]);
+        graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[n]);
+        graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[n]);
+
+        n++;
+    }
+    x->n = y->n = n;
+
+    float range;
+    range = graphdata.xmax - graphdata.xmin;
+    graphdata.xmax += 0.05*range;
+    graphdata.xmin -= 0.05*range;
+    range = graphdata.ymax - graphdata.ymin;
+    graphdata.ymax += 0.05*range;
+    graphdata.ymin -= 0.05*range;
+
+    // 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);
+
+    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:
@@ -1080,13 +1355,19 @@
 
 bool psphotSetVisual (bool mode){}
-bool psphotVisualShowImage (pmConfig *config, pmReadout *readout){}
-bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout){}
-bool psphotVisualShowSignificance (psImage *image){}
-bool psphotVisualShowPeaks (pmConfig *config, const pmFPAview *view, pmDetections *detections){}
-bool psphotVisualShowFootprints (pmConfig *config, const pmFPAview *view, pmDetections *detections){}
-bool psphotVisualShowMoments (pmConfig *config, const pmFPAview *view, psArray *sources){}
-bool psphotVisualShowRoughClass (pmConfig *config, const pmFPAview *view, psArray *sources){}
-bool psphotVisualShowPSF (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources){}
-bool psphotVisualShowLinearFit (pmConfig *config, pmReadout *readout){}
+bool psphotVisualShowImage (pmConfig *config, pmReadout *readout) { return true; }
+bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout) { return true; }
+bool psphotVisualShowSignificance (psImage *image) { return true; }
+bool psphotVisualShowPeaks (pmConfig *config, const pmFPAview *view, pmDetections *detections) { return true; }
+bool psphotVisualShowFootprints (pmConfig *config, const pmFPAview *view, pmDetections *detections) { return true; }
+bool psphotVisualShowMoments (pmConfig *config, const pmFPAview *view, psArray *sources) { return true; }
+bool psphotVisualPlotMoments (pmConfig *config, const pmFPAview *view, psArray *sources) { return true; }
+bool psphotVisualShowRoughClass (pmConfig *config, const pmFPAview *view, psArray *sources) { return true; }
+bool psphotVisualShowPSFStars (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources) { return true; }
+bool psphotVisualShowSatStars (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources) { return true; }
+bool psphotVisualShowPSFModel (pmConfig *config, pmReadout *readout, pmPSF *psf) { return true; }
+bool psphotVisualShowFlags (pmConfig *config, const pmFPAview *view, psArray *sources) { return true; }
+bool psphotVisualSourceSize (pmConfig *config, const pmFPAview *view, psArray *sources) { return true; }
+bool psphotVisualShowResidualImage (pmConfig *config, pmReadout *readout) { return true; }
+bool psphotVisualPlotApResid (pmConfig *config, const pmFPAview *view, psArray *sources) { return true; }
 
 # endif
