Index: /trunk/psModules/src/detrend/pmDark.c
===================================================================
--- /trunk/psModules/src/detrend/pmDark.c	(revision 24818)
+++ /trunk/psModules/src/detrend/pmDark.c	(revision 24819)
@@ -1,2 +1,6 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <pslib.h>
@@ -14,5 +18,4 @@
 #include "pmDetrendThreads.h"
 #include "pmErrorCodes.h"
-
 #include "pmDark.h"
 
@@ -385,4 +388,6 @@
     }
 
+    pmDarkVisualInit(values);
+
     pmReadout *outReadout = output->readouts->data[0];
 
@@ -427,4 +432,8 @@
                 psVectorInit(poly->coeff, NAN);
             }
+
+	    pmDarkVisualPixelFit(pixels, mask);
+	    pmDarkVisualPixelModel(poly, values);
+
             for (int k = 0; k < poly->coeff->n; k++) {
                 pmReadout *ro = output->readouts->data[k]; // Readout of interest
@@ -988,2 +997,152 @@
 }
 
+#if (HAVE_KAPA)
+#include <kapa.h>
+#include "pmKapaPlots.h"
+#include "pmVisual.h"
+
+static int nKapa = 0;
+static int *kapa = NULL;
+static bool plotFlag = true;
+static psArray *xVectors = NULL;
+
+// this init function only gets the ordinates for the first readout...
+bool pmDarkVisualInit(psArray *values) {
+    
+    if (!pmVisualIsVisual()) return true;
+
+    // skip if we have already opened the windows (or if none are requested...)
+    if (nKapa) return true;
+
+    // values has Ninput vectors with Norder elements; we need Norder vectors with Ninput elements...
+    int nOrders = 0;
+    for (int i = 0; i < values->n; i++) {
+	psVector *vect = values->data[i];
+	if (!nOrders) {
+	    nOrders = vect->n;
+	} else {
+	    psAssert (nOrders == vect->n, "mismatch in order vector lengths");
+	}
+    }
+    xVectors = psArrayAlloc(nOrders);
+    for (int i = 0; i < nOrders; i++) {
+	xVectors->data[i] = psVectorAlloc(values->n, PS_TYPE_F32);
+    }
+
+    for (int i = 0; i < values->n; i++) {
+	psVector *vect = values->data[i];
+	for (int j = 0; j < vect->n; j++) {
+	    psVector *xVec = xVectors->data[j];
+	    xVec->data.F32[i] = vect->data.F32[j];
+	}
+    }
+
+    nKapa = nOrders;
+
+    kapa = psAlloc(nKapa*sizeof(int));
+    
+    for (int i = 0; i < nKapa; i++) {
+	kapa[i] = -1;
+	pmVisualInitWindow(&kapa[i], "ppmerge");
+    }
+    return true;
+}
+
+bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask) {
+
+    Graphdata graphdata;
+
+    if (!pmVisualIsVisual()) return true;
+
+    KapaInitGraph(&graphdata);
+
+    psAssert(nKapa == xVectors->n, "inconsistent number of orders %d vs %ld\n", nKapa, xVectors->n);
+
+    psVector *xSub = psVectorAlloc(pixels->n, PS_TYPE_F32);
+    psVector *ySub = psVectorAlloc(pixels->n, PS_TYPE_F32);
+
+    for (int i = 0; i < xVectors->n; i++) {
+	psVector *x = xVectors->data[i];
+
+	// generate vectors of the unmasked values
+	int nSub = 0;
+	for (int j = 0; j < pixels->n; j++) {
+	    if (mask && mask->data.PS_TYPE_VECTOR_MASK_DATA[j]) continue;
+	    xSub->data.F32[nSub] = x->data.F32[j];
+	    ySub->data.F32[nSub] = pixels->data.F32[j];
+	    nSub ++;
+	}
+	xSub->n = ySub->n = nSub;
+	
+	// plot the unmasked values
+	pmVisualScaleGraphdata (&graphdata, xSub, ySub, false);
+	KapaSetGraphData(kapa[i], &graphdata);
+	KapaSetLimits(kapa[i], &graphdata);
+	KapaClearPlots (kapa[i]);
+
+	KapaSetFont (kapa[i], "courier", 14);
+	KapaBox (kapa[i], &graphdata);
+	KapaSendLabel (kapa[i], "ordinate", KAPA_LABEL_XM);
+	KapaSendLabel (kapa[i], "pixel values", KAPA_LABEL_YM);
+
+	graphdata.color = KapaColorByName("black");
+	graphdata.style = 2;
+	graphdata.ptype = 2;
+	KapaPrepPlot  (kapa[i], xSub->n, &graphdata);
+	KapaPlotVector(kapa[i], xSub->n, xSub->data.F32, "x");
+	KapaPlotVector(kapa[i], xSub->n, ySub->data.F32, "y");
+    }
+    pmVisualAskUser (&plotFlag);
+    return true;
+}
+
+bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values) {
+
+    Graphdata graphdata;
+
+    if (!pmVisualIsVisual()) return true;
+
+    KapaInitGraph(&graphdata);
+
+    psAssert(nKapa == xVectors->n, "inconsistent number of orders %d vs %ld\n", nKapa, xVectors->n);
+
+    psVector *yFit = psVectorAlloc(values->n, PS_TYPE_F32);
+
+    for (int i = 0; i < values->n; i++) {
+	psVector *coord = values->data[i];
+	yFit->data.F32[i] = psPolynomialMDEval (poly, coord);
+    }
+
+    for (int i = 0; i < xVectors->n; i++) {
+	psVector *xFit = xVectors->data[i];
+
+	KapaGetGraphData(kapa[i], &graphdata);
+	graphdata.color = KapaColorByName("red");
+	graphdata.style = 2;
+	graphdata.ptype = 7;
+	KapaPrepPlot  (kapa[i], xFit->n, &graphdata);
+	KapaPlotVector(kapa[i], xFit->n, xFit->data.F32, "x");
+	KapaPlotVector(kapa[i], xFit->n, yFit->data.F32, "y");
+    }
+    pmVisualAskUser (&plotFlag);
+    return true;
+}
+
+bool pmDarkVisualCleanup() {
+
+    for (int i = 0; i < nKapa; i++) {
+	KapaClose(kapa[i]);
+    }
+    psFree (kapa);
+    psFree (xVectors);
+    return true;
+}
+
+# else
+
+bool pmDarkVisualInit(psArray *values) { return true; }
+bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask) { return true; }
+bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values) { return true; }
+bool pmDarkVisualCleanup() { return true; }
+
+# endif
Index: /trunk/psModules/src/detrend/pmDark.h
===================================================================
--- /trunk/psModules/src/detrend/pmDark.h	(revision 24818)
+++ /trunk/psModules/src/detrend/pmDark.h	(revision 24819)
@@ -117,4 +117,8 @@
     );
 
+bool pmDarkVisualInit(psArray *values);
+bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask);
+bool pmDarkVisualCleanup();
+bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values);
 
 #endif
