Index: /trunk/psModules/src/detrend/pmBias.c
===================================================================
--- /trunk/psModules/src/detrend/pmBias.c	(revision 19431)
+++ /trunk/psModules/src/detrend/pmBias.c	(revision 19432)
@@ -23,5 +23,5 @@
     PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
     pmReadout *in = job->args->data[0];
-    pmReadout *sub = job->args->data[1];
+    const pmReadout *sub = job->args->data[1];
     float scale  = PS_SCALAR_VALUE(job->args->data[2],F32);
     int xOffset  = PS_SCALAR_VALUE(job->args->data[3],S32);
@@ -29,14 +29,14 @@
     int rowStart = PS_SCALAR_VALUE(job->args->data[5],S32);
     int rowStop  = PS_SCALAR_VALUE(job->args->data[6],S32);
-    bool status = pmBiasSubtractScan (in, sub, scale, xOffset, yOffset, rowStart, rowStop);
-    return status;
-}
-
-bool pmBiasSubtractScan (pmReadout *in, pmReadout *sub, float scale, int xOffset, int yOffset, int rowStart, int rowStop) {
-
+    return pmBiasSubtractScan(in, sub, scale, xOffset, yOffset, rowStart, rowStop);
+}
+
+bool pmBiasSubtractScan(pmReadout *in, const pmReadout *sub, float scale,
+                        int xOffset, int yOffset, int rowStart, int rowStop)
+{
     psImage *inImage  = in->image;      // The input image
     psImage *inMask   = in->mask;       // The input mask
-    psImage *subImage = sub->image;     // The image to be subtracted
-    psImage *subMask  = sub->mask;      // The mask for the subtraction image
+    const psImage *subImage = sub->image; // The image to be subtracted
+    const psImage *subMask  = sub->mask; // The mask for the subtraction image
 
     if (scale == 1.0) {
@@ -62,5 +62,6 @@
 }
 
-// pmBiasSubtractFrame(): this routine will take as input a readout for the input image and a readout for the bias
+// pmBiasSubtractFrame():
+// this routine will take as input a readout for the input image and a readout for the bias
 // image.  The bias image is subtracted in place from the input image.
 bool pmBiasSubtractFrame(pmReadout *in, // Input readout
@@ -129,41 +130,33 @@
 
     for (int rowStart = 0; rowStart < inImage->numRows; rowStart += scanRows) {
-      int rowStop = PS_MIN (rowStart + scanRows, inImage->numRows);
-
-      if (threaded) {
-          // allocate a job, construct the arguments for this job
-          psThreadJob *job = psThreadJobAlloc ("PSMODULES_DETREND_BIAS");
-          psArrayAdd (job->args, 1, in);
-          psArrayAdd (job->args, 1, sub);
-          PS_ARRAY_ADD_SCALAR (job->args, scale, PS_TYPE_F32);
-          PS_ARRAY_ADD_SCALAR (job->args, xOffset, PS_TYPE_S32);
-          PS_ARRAY_ADD_SCALAR (job->args, yOffset, PS_TYPE_S32);
-          PS_ARRAY_ADD_SCALAR (job->args, rowStart, PS_TYPE_S32);
-          PS_ARRAY_ADD_SCALAR (job->args, rowStop, PS_TYPE_S32);
-
-          // ppImageDetrendReadout(config, options, view)
-          if (!psThreadJobAddPending (job)) {
-              psFree(job);
-              return false;
-          }
-          psFree(job);
-      } else {
-          pmBiasSubtractScan (in, sub, scale, xOffset, yOffset, rowStart, rowStop);
-      }
+        int rowStop = PS_MIN(rowStart + scanRows, inImage->numRows);
+
+        if (threaded) {
+            // allocate a job, construct the arguments for this job
+            psThreadJob *job = psThreadJobAlloc("PSMODULES_DETREND_BIAS");
+            psArrayAdd(job->args, 1, in);
+            psArrayAdd(job->args, 1, sub);
+            PS_ARRAY_ADD_SCALAR(job->args, scale, PS_TYPE_F32);
+            PS_ARRAY_ADD_SCALAR(job->args, xOffset, PS_TYPE_S32);
+            PS_ARRAY_ADD_SCALAR(job->args, yOffset, PS_TYPE_S32);
+            PS_ARRAY_ADD_SCALAR(job->args, rowStart, PS_TYPE_S32);
+            PS_ARRAY_ADD_SCALAR(job->args, rowStop, PS_TYPE_S32);
+
+            if (!psThreadJobAddPending(job)) {
+                psFree(job);
+                return false;
+            }
+            psFree(job);
+        } else if (!pmBiasSubtractScan(in, sub, scale, xOffset, yOffset, rowStart, rowStop)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction.");
+            return false;
+        }
     }
 
     if (threaded) {
         // wait here for the threaded jobs to finish
-        if (!psThreadPoolWait(false)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image.");
-            return false;
-        }
-        fprintf (stderr, "success for threaded jobs\n");
-
-        // each job records its own goodPixel values; sum them here
-        // we have only supplied one type of job, so we can assume the types here
-        psThreadJob *job = NULL;
-        while ((job = psThreadJobGetDone()) != NULL) {
-            psFree (job);
+        if (!psThreadPoolWait(true)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction.");
+            return false;
         }
     }
Index: /trunk/psModules/src/detrend/pmBias.h
===================================================================
--- /trunk/psModules/src/detrend/pmBias.h	(revision 19431)
+++ /trunk/psModules/src/detrend/pmBias.h	(revision 19432)
@@ -5,6 +5,6 @@
  * @author Paul Price, IfA
  *
- * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
- * @date $Date: 2008-08-30 02:28:07 $
+ * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2008-09-09 04:10:14 $
  * Copyright 2004--2006 Institute for Astronomy, University of Hawaii
  */
@@ -27,5 +27,6 @@
                    );
 
-// pmBiasSubtractFrame(): this routine will take as input a readout for the input image and a readout for the bias
+// pmBiasSubtractFrame
+// this routine will take as input a readout for the input image and a readout for the bias
 // image.  The bias image is subtracted in place from the input image.
 bool pmBiasSubtractFrame(pmReadout *in, // Input readout
@@ -34,6 +35,16 @@
     );
 
-bool pmBiasSubtractScan_Threaded(psThreadJob *job);
-bool pmBiasSubtractScan (pmReadout *in, pmReadout *sub, float scan, int xOffset, int yOffset, int rowStart, int rowStop);
+/// Thread entry point for bias subtraction
+bool pmBiasSubtractScan_Threaded(psThreadJob *job ///< Job to execute
+    );
+
+/// Do bias subtraction for a scan
+bool pmBiasSubtractScan(
+    pmReadout *in,                      ///< Input image to correct
+    const pmReadout *sub,               ///< Bias+dark image to subtract
+    float scale,                        ///< Scale to apply
+    int xOffset, int yOffset,           ///< Offset between input and bias images
+    int rowStart, int rowStop           ///< Scan range
+    );
 
 /// @}
Index: /trunk/psModules/src/detrend/pmDark.c
===================================================================
--- /trunk/psModules/src/detrend/pmDark.c	(revision 19431)
+++ /trunk/psModules/src/detrend/pmDark.c	(revision 19432)
@@ -222,20 +222,28 @@
 
     // these calls allocate and save the requested images on the output analysis metadata
-    psImage *counts = pmReadoutSetAnalysisImage(output->readouts->data[0], PM_READOUT_STACK_ANALYSIS_COUNT, numCols, numRows, PS_TYPE_U16, 0);
+    psImage *counts = pmReadoutSetAnalysisImage(output->readouts->data[0], PM_READOUT_STACK_ANALYSIS_COUNT,
+                                                numCols, numRows, PS_TYPE_U16, 0);
     if (!counts) {
         return false;
     }
-    psImage *sigma = pmReadoutSetAnalysisImage(output->readouts->data[0], PM_READOUT_STACK_ANALYSIS_SIGMA, numCols, numRows, PS_TYPE_F32, NAN);
+    psImage *sigma = pmReadoutSetAnalysisImage(output->readouts->data[0], PM_READOUT_STACK_ANALYSIS_SIGMA,
+                                               numCols, numRows, PS_TYPE_F32, NAN);
     if (!sigma) {
         return false;
     }
 
-    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_ORDINATES, PS_DATA_ARRAY | PS_META_REPLACE, "Dark ordinates", ordinates);
-    psMetadataAddStr(output->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_NORM, PS_META_REPLACE, "Dark normalisation", normConcept);
-
-    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.VALUES",  PS_DATA_ARRAY  | PS_META_REPLACE, "Dark values", values);
-    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.RO.MASK", PS_DATA_VECTOR | PS_META_REPLACE, "Dark Readout Mask", roMask);
-    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.NORM",    PS_DATA_VECTOR | PS_META_REPLACE, "Dark norm", norm);
-    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.ORDERS",  PS_DATA_VECTOR | PS_META_REPLACE, "Dark orders", orders);
+    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_ORDINATES,
+                     PS_DATA_ARRAY | PS_META_REPLACE, "Dark ordinates", ordinates);
+    psMetadataAddStr(output->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_NORM, PS_META_REPLACE,
+                     "Dark normalisation", normConcept);
+
+    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.VALUES",  PS_DATA_ARRAY  | PS_META_REPLACE,
+                     "Dark values", values);
+    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.RO.MASK", PS_DATA_VECTOR | PS_META_REPLACE,
+                     "Dark Readout Mask", roMask);
+    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.NORM",    PS_DATA_VECTOR | PS_META_REPLACE,
+                     "Dark norm", norm);
+    psMetadataAddPtr(output->analysis, PS_LIST_TAIL, "DARK.ORDERS",  PS_DATA_VECTOR | PS_META_REPLACE,
+                     "Dark orders", orders);
 
     for (int i = 0; i < numTerms; i++) {
@@ -272,7 +280,10 @@
 
     // retrieve the required parameter vectors
-    psArray *values  = psMetadataLookupPtr(&mdok, output->analysis, "DARK.VALUES");  psAssert (values, "values not supplied");
-    psVector *roMask = psMetadataLookupPtr(&mdok, output->analysis, "DARK.RO.MASK"); psAssert (roMask, "roMask not supplied");
-    psVector *orders = psMetadataLookupPtr(&mdok, output->analysis, "DARK.ORDERS");  psAssert (orders, "orders not supplied");
+    psArray *values  = psMetadataLookupPtr(&mdok, output->analysis, "DARK.VALUES");
+    psAssert(values, "values not supplied");
+    psVector *roMask = psMetadataLookupPtr(&mdok, output->analysis, "DARK.RO.MASK");
+    psAssert(roMask, "roMask not supplied");
+    psVector *orders = psMetadataLookupPtr(&mdok, output->analysis, "DARK.ORDERS");
+    psAssert(orders, "orders not supplied");
 
     psPolynomialMD *poly = psPolynomialMDAlloc(orders); // Polynomial for fitting
@@ -307,10 +318,10 @@
         int yOut = i - outReadout->row0; // y position on output readout
 
-# ifdef SHOW_BUSY
+#ifdef SHOW_BUSY
         if (psTraceGetLevel("psModules.detrend") > 9) {
             printf("Processing row %d\r", i);
             fflush(stdout);
         }
-# endif
+#endif
 
         for (int j = minInputCols; j < maxInputCols; j++) {
@@ -337,18 +348,4 @@
             }
 
-            // XXX test
-            if (0 && (i == 377) && (j == 80)) {
-                FILE *f = fopen ("test.dat", "w");
-                for (int r = 0; r < inputs->n; r++) {
-                    fprintf (f, "%d %d  %d  ", i, j, mask->data.U8[r]);
-                    psVector *value = values->data[r];
-                    for (int tmpj = 0; tmpj < value->n; tmpj++) {
-                        fprintf (f, "%f ", value->data.F32[tmpj]);
-                    }
-                    fprintf (f, "%f\n", pixels->data.F32[r]);
-                }
-                fclose (f);
-            }
-
             if (!psPolynomialMDClipFit(poly, pixels, NULL, mask, maskVal, values, iter, rej)) {
                 psErrorClear();         // Nothing we can do about it
@@ -367,5 +364,4 @@
     psFree(mask);
 
-    fprintf (stderr, "done with combine %x : %f sec\n", (unsigned int) id, psTimerMark (name));
     return true;
 }
@@ -375,24 +371,26 @@
     PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
 
-    pmReadout *readout   = job->args->data[0];
-    pmCell *dark         = job->args->data[1];
-    psPolynomialMD *poly = job->args->data[2];
-    psVector *values     = job->args->data[3];
-
-    psMaskType bad = PS_SCALAR_VALUE(job->args->data[4],U8);
-    bool doNorm    = PS_SCALAR_VALUE(job->args->data[5],U8);
-    float norm     = PS_SCALAR_VALUE(job->args->data[6],F32);
-    int rowStart   = PS_SCALAR_VALUE(job->args->data[7],S32);
-    int rowStop    = PS_SCALAR_VALUE(job->args->data[8],S32);
-    bool status = pmDarkApplyScan (readout, dark, poly, values, bad, doNorm, norm, rowStart, rowStop);
-    return status;
-}
-
-bool pmDarkApplyScan (pmReadout *readout, const pmCell *dark, psPolynomialMD *poly, psVector *values, psMaskType bad, bool doNorm, float norm, int rowStart, int rowStop) {
-
+    pmReadout *readout     = job->args->data[0]; // Readout to correct
+    pmCell *dark           = job->args->data[1]; // Dark to apply
+    const psVector *orders = job->args->data[2]; // Polynomial orders for each ordinate
+    const psVector *values = job->args->data[3]; // Values for each ordinate
+
+    psMaskType bad = PS_SCALAR_VALUE(job->args->data[4], U8); // Mask value to give bad pixels
+    bool doNorm    = PS_SCALAR_VALUE(job->args->data[5], U8); // Normalise values?
+    float norm     = PS_SCALAR_VALUE(job->args->data[6], F32); // Value by which to normalise
+    int rowStart   = PS_SCALAR_VALUE(job->args->data[7], S32); // Starting row for scan
+    int rowStop    = PS_SCALAR_VALUE(job->args->data[8], S32); // Stopping row for scan
+
+    return pmDarkApplyScan(readout, dark, orders, values, bad, doNorm, norm, rowStart, rowStop);
+}
+
+bool pmDarkApplyScan(pmReadout *readout, const pmCell *dark, const psVector *orders, const psVector *values,
+                     psMaskType bad, bool doNorm, float norm, int rowStart, int rowStop)
+{
     int numCols = readout->image->numCols;
     int numTerms = dark->readouts->n;   // Number of polynomial terms
 
-    // thread here by scan
+    psPolynomialMD *poly = psPolynomialMDAlloc(orders); // Polynomial to apply
+
     for (int y = rowStart; y < rowStop; y++) {
         for (int x = 0; x < numCols; x++) {
@@ -411,4 +409,6 @@
         }
     }
+    psFree(poly);
+
     return true;
 }
@@ -478,7 +478,4 @@
     }
 
-    psPolynomialMD *poly = psPolynomialMDAlloc(orders); // Polynomial to apply
-    psFree(orders);
-
     // thread here by scan
 
@@ -491,46 +488,44 @@
 
     for (int rowStart = 0; rowStart < readout->image->numRows; rowStart += scanRows) {
-      int rowStop = PS_MIN (rowStart + scanRows, readout->image->numRows);
-
-      if (threaded) {
-          // allocate a job, construct the arguments for this job
-          psThreadJob *job = psThreadJobAlloc ("PSMODULES_DETREND_DARK");
-          psArrayAdd (job->args, 1, readout);
-          psArrayAdd (job->args, 1, dark);
-          psArrayAdd (job->args, 1, poly);
-          psArrayAdd (job->args, 1, values);
-          PS_ARRAY_ADD_SCALAR (job->args, bad, PS_TYPE_MASK);
-          PS_ARRAY_ADD_SCALAR (job->args, doNorm, PS_TYPE_U8);
-          PS_ARRAY_ADD_SCALAR (job->args, norm, PS_TYPE_F32);
-          PS_ARRAY_ADD_SCALAR (job->args, rowStart, PS_TYPE_S32);
-          PS_ARRAY_ADD_SCALAR (job->args, rowStop, PS_TYPE_S32);
-
-          // ppImageDetrendReadout(config, options, view)
-          if (!psThreadJobAddPending (job)) {
-              psFree(job);
-              return false;
-          }
-          psFree(job);
-      } else {
-          pmDarkApplyScan (readout, dark, poly, values, bad, doNorm, norm, rowStart, rowStop);
-      }
+        int rowStop = PS_MIN(rowStart + scanRows, readout->image->numRows);
+
+        if (threaded) {
+            psThreadJob *job = psThreadJobAlloc("PSMODULES_DETREND_DARK");
+            psArrayAdd(job->args, 1, readout);
+            psArrayAdd(job->args, 1, dark);
+            psArrayAdd(job->args, 1, orders);
+            psArrayAdd(job->args, 1, values);
+            PS_ARRAY_ADD_SCALAR(job->args, bad, PS_TYPE_MASK);
+            PS_ARRAY_ADD_SCALAR(job->args, doNorm, PS_TYPE_U8);
+            PS_ARRAY_ADD_SCALAR(job->args, norm, PS_TYPE_F32);
+            PS_ARRAY_ADD_SCALAR(job->args, rowStart, PS_TYPE_S32);
+            PS_ARRAY_ADD_SCALAR(job->args, rowStop, PS_TYPE_S32);
+
+            if (!psThreadJobAddPending (job)) {
+                psFree(job);
+                psFree(orders);
+                psFree(values);
+                return false;
+            }
+            psFree(job);
+        } else if (!pmDarkApplyScan(readout, dark, orders, values, bad, doNorm, norm, rowStart, rowStop)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to apply dark.");
+            psFree(orders);
+            psFree(values);
+            return false;
+        }
     }
 
     if (threaded) {
         // wait here for the threaded jobs to finish
-        if (!psThreadPoolWait(false)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image.");
+        if (!psThreadPoolWait(true)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to apply dark.");
+            psFree(orders);
+            psFree(values);
             return false;
         }
-        fprintf (stderr, "success for threaded jobs\n");
-
-        // free the done jobs
-        psThreadJob *job = NULL;
-        while ((job = psThreadJobGetDone()) != NULL) {
-            psFree (job);
-        }
-    }
-
-    psFree(poly);
+    }
+
+    psFree(orders);
     psFree(values);
 
Index: /trunk/psModules/src/detrend/pmDark.h
===================================================================
--- /trunk/psModules/src/detrend/pmDark.h	(revision 19431)
+++ /trunk/psModules/src/detrend/pmDark.h	(revision 19432)
@@ -40,6 +40,18 @@
     );
 
-bool pmDarkApplyScan_Threaded(psThreadJob *job);
-bool pmDarkApplyScan (pmReadout *readout, const pmCell *dark, psPolynomialMD *poly, psVector *values, psMaskType bad, bool doNorm, float norm, int rowStart, int rowStop);
+// Thread entry point for pmDarkApplyScan
+bool pmDarkApplyScan_Threaded(psThreadJob *job // Job to execute
+    );
+
+// Apply the dark correction to a scan
+bool pmDarkApplyScan(pmReadout *readout, // Readout to correct
+                     const pmCell *dark, // Dark to apply
+                     const psVector *orders, // Polynomial orders for each ordinate
+                     const psVector *values, // Values for each ordinate
+                     psMaskType bad,    // Value to give bad pixels
+                     bool doNorm,       // Normalise values?
+                     float norm,        // Value by which to normalise
+                     int rowStart, int rowStop // Scan range to work on
+    );
 
 // Apply dark
Index: /trunk/psModules/src/detrend/pmFlatField.c
===================================================================
--- /trunk/psModules/src/detrend/pmFlatField.c	(revision 19431)
+++ /trunk/psModules/src/detrend/pmFlatField.c	(revision 19432)
@@ -17,8 +17,8 @@
     PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
 
-    psImage *inImage   = job->args->data[0];
-    psImage *inMask    = job->args->data[1];
-    psImage *flatImage = job->args->data[2];
-    psImage *flatMask  = job->args->data[3];
+    psImage *inImage   = job->args->data[0]; // Input image
+    psImage *inMask    = job->args->data[1]; // Input mask
+    const psImage *flatImage = job->args->data[2]; // Flat-field image
+    const psImage *flatMask  = job->args->data[3]; // Flat-field mask
 
     psMaskType badFlat = PS_SCALAR_VALUE(job->args->data[4],U8);
@@ -27,6 +27,6 @@
     int rowStart       = PS_SCALAR_VALUE(job->args->data[7],S32);
     int rowStop        = PS_SCALAR_VALUE(job->args->data[8],S32);
-    bool status = pmFlatFieldScan (inImage, inMask, flatImage, flatMask, badFlat, xOffset, yOffset, rowStart, rowStop);
-    return status;
+    return pmFlatFieldScan(inImage, inMask, flatImage, flatMask, badFlat,
+                           xOffset, yOffset, rowStart, rowStop);
 }
 
@@ -50,6 +50,7 @@
     break;
 
-bool pmFlatFieldScan (psImage *inImage, psImage *inMask, psImage *flatImage, psImage *flatMask, psMaskType badFlat, int xOffset, int yOffset, int rowStart, int rowStop) {
-
+bool pmFlatFieldScan(psImage *inImage, psImage *inMask, const psImage *flatImage, const psImage *flatMask,
+                     psMaskType badFlat, int xOffset, int yOffset, int rowStart, int rowStop)
+{
     switch (inImage->type.type) {
         FLAT_DIVISION_CASE(U8,  0);
@@ -138,27 +139,28 @@
 
     for (int rowStart = 0; rowStart < inImage->numRows; rowStart += scanRows) {
-      int rowStop = PS_MIN (rowStart + scanRows, inImage->numRows);
+      int rowStop = PS_MIN(rowStart + scanRows, inImage->numRows);
 
       if (threaded) {
           // allocate a job, construct the arguments for this job
-          psThreadJob *job = psThreadJobAlloc ("PSMODULES_DETREND_FLAT");
-          psArrayAdd (job->args, 1, inImage);
-          psArrayAdd (job->args, 1, inMask);
-          psArrayAdd (job->args, 1, flatImage);
-          psArrayAdd (job->args, 1, flatMask);
-          PS_ARRAY_ADD_SCALAR (job->args, badFlat, PS_TYPE_U8);
-          PS_ARRAY_ADD_SCALAR (job->args, xOffset, PS_TYPE_S32);
-          PS_ARRAY_ADD_SCALAR (job->args, yOffset, PS_TYPE_S32);
-          PS_ARRAY_ADD_SCALAR (job->args, rowStart, PS_TYPE_S32);
-          PS_ARRAY_ADD_SCALAR (job->args, rowStop, PS_TYPE_S32);
+          psThreadJob *job = psThreadJobAlloc("PSMODULES_DETREND_FLAT");
+          psArrayAdd(job->args, 1, inImage);
+          psArrayAdd(job->args, 1, inMask);
+          psArrayAdd(job->args, 1, flatImage);
+          psArrayAdd(job->args, 1, flatMask);
+          PS_ARRAY_ADD_SCALAR(job->args, badFlat, PS_TYPE_U8);
+          PS_ARRAY_ADD_SCALAR(job->args, xOffset, PS_TYPE_S32);
+          PS_ARRAY_ADD_SCALAR(job->args, yOffset, PS_TYPE_S32);
+          PS_ARRAY_ADD_SCALAR(job->args, rowStart, PS_TYPE_S32);
+          PS_ARRAY_ADD_SCALAR(job->args, rowStop, PS_TYPE_S32);
 
-          // ppImageDetrendReadout(config, options, view)
-          if (!psThreadJobAddPending (job)) {
+          if (!psThreadJobAddPending(job)) {
               psFree(job);
               return false;
           }
           psFree(job);
-      } else {
-          pmFlatFieldScan (inImage, inMask, flatImage, flatMask, badFlat, xOffset, yOffset, rowStart, rowStop);
+      } else if (!pmFlatFieldScan(inImage, inMask, flatImage, flatMask, badFlat,
+                                  xOffset, yOffset, rowStart, rowStop)) {
+          psError(PS_ERR_UNKNOWN, false, "Unable to flat-field image.");
+          return false;
       }
     }
@@ -166,14 +168,7 @@
     if (threaded) {
         // wait here for the threaded jobs to finish
-        if (!psThreadPoolWait(false)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image.");
+        if (!psThreadPoolWait(true)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to flat-field image.");
             return false;
-        }
-        fprintf (stderr, "success for threaded jobs\n");
-
-        // free done jobs
-        psThreadJob *job = NULL;
-        while ((job = psThreadJobGetDone()) != NULL) {
-            psFree (job);
         }
     }
@@ -187,5 +182,4 @@
     psFree(timeString);
 
-
     return true;
 }
Index: /trunk/psModules/src/detrend/pmFlatField.h
===================================================================
--- /trunk/psModules/src/detrend/pmFlatField.h	(revision 19431)
+++ /trunk/psModules/src/detrend/pmFlatField.h	(revision 19432)
@@ -5,6 +5,6 @@
  * @author Paul Price, IfA
  *
- * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
- * @date $Date: 2008-08-30 02:28:07 $
+ * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2008-09-09 04:10:14 $
  * Copyright 2004-2006 Institute for Astronomy, University of Hawaii
  */
@@ -28,6 +28,18 @@
                 );
 
-bool pmFlatFieldScan_Threaded(psThreadJob *job);
-bool pmFlatFieldScan (psImage *inImage, psImage *inMask, psImage *flatImage, psImage *flatMask, psMaskType badFlag, int xOffset, int yOffset, int rowStart, int rowStop);
+/// Thread entry point for flat-fielding
+bool pmFlatFieldScan_Threaded(psThreadJob *job ///< Job to exectute
+    );
+
+/// Flat-field a scan
+bool pmFlatFieldScan(
+    psImage *inImage,                   ///< Input image to correct
+    psImage *inMask,                    ///< Input mask image
+    const psImage *flatImage,           ///< Flat-field image
+    const psImage *flatMask,            ///< Flat-field mask
+    psMaskType badFlag,                 ///< Mask value to give bad pixels
+    int xOffset, int yOffset,           ///< Offset between input and flat-field
+    int rowStart, int rowStop           ///< Scan range
+    );
 
 
Index: /trunk/psModules/src/detrend/pmShutterCorrection.c
===================================================================
--- /trunk/psModules/src/detrend/pmShutterCorrection.c	(revision 19431)
+++ /trunk/psModules/src/detrend/pmShutterCorrection.c	(revision 19432)
@@ -661,5 +661,5 @@
 
     psImage *image        = job->args->data[0];
-    psImage *shutterImage = job->args->data[1];
+    const psImage *shutterImage = job->args->data[1];
     psImage *mask         = job->args->data[2];
 
@@ -668,9 +668,9 @@
     int rowStart     = PS_SCALAR_VALUE(job->args->data[5],S32);
     int rowStop      = PS_SCALAR_VALUE(job->args->data[6],S32);
-    bool status = pmShutterCorrectionApplyScan (image, shutterImage, mask, exptime, blank, rowStart, rowStop);
-    return status;
-}
-
-bool pmShutterCorrectionApplyScan(psImage *image, psImage *shutterImage, psImage *mask, float exptime, psMaskType blank, int rowStart, int rowStop)
+    return pmShutterCorrectionApplyScan (image, shutterImage, mask, exptime, blank, rowStart, rowStop);
+}
+
+bool pmShutterCorrectionApplyScan(psImage *image, const psImage *shutterImage, psImage *mask, float exptime,
+                                  psMaskType blank, int rowStart, int rowStop)
 {
     for (int y = rowStart; y < rowStop; y++) {
@@ -753,9 +753,10 @@
             }
         }
-        psMetadataAddF32 (cell->concepts, PS_LIST_TAIL, "CELL.EXPOSURE", PS_META_REPLACE, "exposure time re-normalized to 1.0", 1.0); // Exposure time
+        psMetadataAddF32(cell->concepts, PS_LIST_TAIL, "CELL.EXPOSURE", PS_META_REPLACE,
+                         "exposure time re-normalized to 1.0", 1.0); // Exposure time
         psString line = NULL;
-        psStringAppend (&line, "extreme exposure time %f, re-normalized to 1.0", exptime);
+        psStringAppend(&line, "extreme exposure time %f, re-normalized to 1.0", exptime);
         psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, line, "");
-        psFree (line);
+        psFree(line);
     } else {
         for (int rowStart = 0; rowStart < image->numRows; rowStart += scanRows) {
@@ -764,35 +765,31 @@
             if (threaded) {
                 // allocate a job, construct the arguments for this job
-                psThreadJob *job = psThreadJobAlloc ("PSMODULES_DETREND_SHUTTER");
-                psArrayAdd (job->args, 1, image);
-                psArrayAdd (job->args, 1, shutterImage);
-                psArrayAdd (job->args, 1, mask);
-                PS_ARRAY_ADD_SCALAR (job->args, exptime, PS_TYPE_F32);
-                PS_ARRAY_ADD_SCALAR (job->args, blank, PS_TYPE_MASK);
-                PS_ARRAY_ADD_SCALAR (job->args, rowStart, PS_TYPE_S32);
-                PS_ARRAY_ADD_SCALAR (job->args, rowStop, PS_TYPE_S32);
-
-                // ppImageDetrendReadout(config, options, view)
-                if (!psThreadJobAddPending (job)) {
+                psThreadJob *job = psThreadJobAlloc("PSMODULES_DETREND_SHUTTER");
+                psArrayAdd(job->args, 1, image);
+                psArrayAdd(job->args, 1, shutterImage);
+                psArrayAdd(job->args, 1, mask);
+                PS_ARRAY_ADD_SCALAR(job->args, exptime, PS_TYPE_F32);
+                PS_ARRAY_ADD_SCALAR(job->args, blank, PS_TYPE_MASK);
+                PS_ARRAY_ADD_SCALAR(job->args, rowStart, PS_TYPE_S32);
+                PS_ARRAY_ADD_SCALAR(job->args, rowStop, PS_TYPE_S32);
+
+                if (!psThreadJobAddPending(job)) {
                     psFree(job);
                     return false;
                 }
                 psFree(job);
-            } else {
-                pmShutterCorrectionApplyScan (image, shutterImage, mask, exptime, blank, rowStart, rowStop);
+            } else if (!pmShutterCorrectionApplyScan(image, shutterImage, mask, exptime, blank,
+                                                     rowStart, rowStop)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to apply shutter correction.");
+                psFree(shutterImage);
+                return false;
             }
         }
         if (threaded) {
             // wait here for the threaded jobs to finish
-            if (!psThreadPoolWait(false)) {
-                psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image.");
+            if (!psThreadPoolWait(true)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to apply shutter correction.");
+                psFree(shutterImage);
                 return false;
-            }
-            fprintf (stderr, "success for threaded jobs\n");
-
-            // free the done jobs
-            psThreadJob *job = NULL;
-            while ((job = psThreadJobGetDone()) != NULL) {
-                psFree (job);
             }
         }
@@ -1024,5 +1021,6 @@
 }
 
-bool pmShutterCorrectionGeneratePrepare(pmReadout *shutter, pmReadout *pattern, const psArray *inputs, psMaskType maskVal)
+bool pmShutterCorrectionGeneratePrepare(pmReadout *shutter, pmReadout *pattern, const psArray *inputs,
+                                        psMaskType maskVal)
 {
     PS_ASSERT_PTR_NON_NULL(shutter, false);
@@ -1043,9 +1041,11 @@
     }
 
-    psImage *nums = pmReadoutSetAnalysisImage(shutter, PM_READOUT_STACK_ANALYSIS_COUNT, numCols, numRows, PS_TYPE_U16, 0); // Image with number fitted per pixel
+    psImage *nums = pmReadoutSetAnalysisImage(shutter, PM_READOUT_STACK_ANALYSIS_COUNT, numCols, numRows,
+                                              PS_TYPE_U16, 0); // Image with number fitted per pixel
     if (!nums) {
         return false;
     }
-    psImage *sigma = pmReadoutSetAnalysisImage(shutter, PM_READOUT_STACK_ANALYSIS_SIGMA, numCols, numRows, PS_TYPE_F32, NAN); // Image with stdev per pixel
+    psImage *sigma = pmReadoutSetAnalysisImage(shutter, PM_READOUT_STACK_ANALYSIS_SIGMA, numCols, numRows,
+                                               PS_TYPE_F32, NAN); // Image with stdev per pixel
     if (!sigma) {
         return false;
Index: /trunk/psModules/src/detrend/pmShutterCorrection.h
===================================================================
--- /trunk/psModules/src/detrend/pmShutterCorrection.h	(revision 19431)
+++ /trunk/psModules/src/detrend/pmShutterCorrection.h	(revision 19432)
@@ -5,6 +5,6 @@
  * @author Paul Price, IfA
  *
- * @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
- * @date $Date: 2008-08-30 02:28:07 $
+ * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2008-09-09 04:10:14 $
  * Copyright 2006 Institute for Astronomy, University of Hawaii
  */
@@ -124,6 +124,18 @@
     );
 
-bool pmShutterCorrectionApplyScan_Threaded(psThreadJob *job);
-bool pmShutterCorrectionApplyScan(psImage *image, psImage *shutterImage, psImage *mask, float exptime, psMaskType blank, int rowStart, int rowStop);
+/// Thread entry point for applying a shutter correction
+bool pmShutterCorrectionApplyScan_Threaded(
+    psThreadJob *job                    ///< Job to execute
+    );
+
+/// Apply the shutter correction to a scan
+bool pmShutterCorrectionApplyScan(
+    psImage *image,                     ///< Input image to correct
+    const psImage *shutterImage,        ///< Shutter correction image
+    psImage *mask,                      ///< Input mask image
+    float exptime,                      ///< Exposure time to which to correct
+    psMaskType blank,                   ///< Mask value to give blank pixels
+    int rowStart, int rowStop           ///< Range of scan
+    );
 
 /// Apply a shutter correction
@@ -193,5 +205,6 @@
 
 // prepare outputs for shutter correction
-bool pmShutterCorrectionGeneratePrepare(pmReadout *shutter, pmReadout *pattern, const psArray *inputs, psMaskType maskVal);
+bool pmShutterCorrectionGeneratePrepare(pmReadout *shutter, pmReadout *pattern, const psArray *inputs,
+                                        psMaskType maskVal);
 
 /// @}
