Index: /trunk/ppMerge/src/ppMergeCombine.c
===================================================================
--- /trunk/ppMerge/src/ppMergeCombine.c	(revision 16841)
+++ /trunk/ppMerge/src/ppMergeCombine.c	(revision 16842)
@@ -16,7 +16,8 @@
 #include "ppMergeVersion.h"
 
+#define TESTING
+
+
 #if 0
-static psMemId memId = 0;
-
 static FILE *dumpFile = NULL;
 
@@ -36,6 +37,8 @@
     exit(EXIT_FAILURE);
 }
-
-
+#endif
+
+#if 0
+static psMemId memId = 0;
 static void memDump(void)
 {
@@ -52,5 +55,7 @@
     psFree(leaks);
 }
-
+#endif
+
+#if 0
 static void memCheck(void)
 {
@@ -73,5 +78,5 @@
         psTrace("ppMerge", 0, "Memory in use: %zd\n", totalSize);
         psTrace("ppMerge", 0, "Largest block: %ld\n", largest);
-        psTrace("ppMerge", 0, "sbrk(): %zd\n", sbrk(0));
+        psTrace("ppMerge", 0, "sbrk(): %p\n", sbrk(0));
     }
     return;
@@ -119,18 +124,20 @@
     }
     while ((chip = pmFPAviewNextChip(view, fpa, 1))) {
-        if (chip->hdu) {
-            // Data will exist soon
-            pmFPAUpdateNames(data->out, chip, NULL);
-            chip->data_exists = true;
-        }
+        if (!chip->hdu) {
+            continue;
+        }
+        // Data will exist soon
+        pmFPAUpdateNames(data->out, chip, NULL);
+        chip->data_exists = true;
         pmChipWrite(chip, data->outFile, config->database, true, false); // Write header only
         pmCell *cell;                   // Cell of interest
         while ((cell = pmFPAviewNextCell(view, fpa, 1))) {
             cellNum++;
-            if (cell->hdu) {
-                // Data will exist soon
-                pmFPAUpdateNames(data->out, chip, cell);
-                chip->data_exists = cell->data_exists = true;
-            }
+            if (!cell->hdu) {
+                continue;
+            }
+            // Data will exist soon
+            pmFPAUpdateNames(data->out, chip, cell);
+            chip->data_exists = cell->data_exists = true;
             pmCellWrite(cell, data->outFile, config->database, true); // Write header only
             pmReadout *readout = pmReadoutAlloc(cell); // Output readout of interest
@@ -197,8 +204,8 @@
 
                         // If we're combining with weights, we want to generate weights.
-                        if (options->combine->weights) {
+                        if (options->combine->weights && !options->dark) {
 
                             // If it's a bias or dark, set the gain to zero: noise only contributed by read
-                            if ((!options->zero && !options->scale) || options->darktime) {
+                            if (!options->zero && !options->scale) {
                                 pmReadoutSetWeight(stack->data[i], false);
                             } else {
@@ -209,5 +216,6 @@
                         numRead++;
                     } else {
-			psTrace("ppMerge", 3, "Finished reading file %d, chip %d, cell %d, scan %d\n", i, view->chip, view->cell, numScan);
+                        psTrace("ppMerge", 3, "Finished reading file %d, chip %d, cell %d, scan %d\n",
+                                i, view->chip, view->cell, numScan);
                     }
 
@@ -220,4 +228,7 @@
                                                     options->shutterIter, options->shutterRej,
                                                     options->combine->maskVal);
+                    } else if (options->dark) {
+                        pmDarkCombine(cell, stack, options->darkOrdinates, options->combine->iter,
+                                      options->combine->rej, options->combine->maskVal);
                     } else {
                         pmReadoutCombine(readout, stack, cellZeros, cellScales, options->combine);
@@ -246,4 +257,5 @@
             psFree(stack);
 
+#if 0
             // Set the dark time for the output image, since we normalised
             if (options->darktime) {
@@ -253,4 +265,5 @@
                 expItem->data.F32 = 1.0;
             }
+#endif
 
             // Measure the fringes for this cell
@@ -334,9 +347,12 @@
             if (cell->hdu && !cell->hdu->blankPHU) {
                 psTrace("ppMerge", 5, "Writing out cell HDU.\n");
-                pmCellWrite(cell, data->outFile, config->database, false);
-                if (options->fringe) {
-                    pmCellWriteTable(data->outFile, cell, "FRINGE");
-                }
-
+                if (options->dark) {
+                    pmCellWriteDark(cell, data->outFile, config->database, false);
+                } else {
+                    pmCellWrite(cell, data->outFile, config->database, false);
+                    if (options->fringe) {
+                        pmCellWriteTable(data->outFile, cell, "FRINGE");
+                    }
+                }
                 pmCellFreeData(cell);
             }
@@ -354,7 +370,11 @@
         if (chip->hdu && !chip->hdu->blankPHU) {
             psTrace("ppMerge", 5, "Writing out chip HDU.\n");
-            pmChipWrite(chip, data->outFile, config->database, false, false);
-            if (options->fringe) {
-                pmChipWriteTable(data->outFile, chip, "FRINGE");
+            if (options->dark) {
+                pmChipWriteDark(chip, data->outFile, config->database, false, false);
+            } else {
+                pmChipWrite(chip, data->outFile, config->database, false, false);
+                if (options->fringe) {
+                    pmChipWriteTable(data->outFile, chip, "FRINGE");
+                }
             }
 
@@ -373,7 +393,11 @@
         // Write the pixels
         psTrace("ppMerge", 5, "Writing out FPA HDU.\n");
-        pmFPAWrite(data->out, data->outFile, config->database, false, false);
-        if (options->fringe) {
-            pmFPAWriteTable(data->outFile, fpa, "FRINGE");
+        if (options->dark) {
+            pmFPAWriteDark(data->out, data->outFile, config->database, false, false);
+        } else {
+            pmFPAWrite(data->out, data->outFile, config->database, false, false);
+            if (options->fringe) {
+                pmFPAWriteTable(data->outFile, fpa, "FRINGE");
+            }
         }
     }
Index: /trunk/ppMerge/src/ppMergeOptions.c
===================================================================
--- /trunk/ppMerge/src/ppMergeOptions.c	(revision 16841)
+++ /trunk/ppMerge/src/ppMergeOptions.c	(revision 16842)
@@ -10,4 +10,6 @@
 #include "ppMerge.h"
 #include "ppMergeOptions.h"
+
+#define ARRAY_BUFFER 4                  // Number of values to add at once
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -34,5 +36,5 @@
     options->zero = false;
     options->scale = false;
-    options->darktime = false;
+    options->dark = false;
     options->fringe = false;
     options->shutter = false;
@@ -65,4 +67,5 @@
     options->badMask = 0x00;
     options->growPixels = 0;
+    options->darkOrdinates = NULL;
     return options;
 }
@@ -174,5 +177,5 @@
             options->zero = false;
             options->scale = false;
-            options->darktime = false;
+            options->dark = false;
             options->fringe = false;
             options->shutter = false;
@@ -181,5 +184,5 @@
             options->zero = false;
             options->scale = false;
-            options->darktime = true;
+            options->dark = true;
             options->fringe = false;
             options->shutter = false;
@@ -188,5 +191,5 @@
             options->zero = false;
             options->scale = true;
-            options->darktime = false;
+            options->dark = false;
             options->fringe = false;
             options->shutter = false;
@@ -195,5 +198,5 @@
             options->zero = false;
             options->scale = true;
-            options->darktime = false;
+            options->dark = false;
             options->fringe = false;
             options->shutter = false;
@@ -202,5 +205,5 @@
             options->zero = false;
             options->scale = true;
-            options->darktime = false;
+            options->dark = false;
             options->fringe = false;
             options->shutter = false;
@@ -209,5 +212,5 @@
             options->zero = true;
             options->scale = true;
-            options->darktime = false;
+            options->dark = false;
             options->fringe = true;
             options->shutter = false;
@@ -216,5 +219,5 @@
             options->zero = false;
             options->scale = false;
-            options->darktime = false;
+            options->dark = false;
             options->fringe = false;
             options->shutter = true;
@@ -225,5 +228,5 @@
             options->zero = false;
             options->scale = false;
-            options->darktime = false;
+            options->dark = false;
             options->fringe = false;
             options->shutter = false;
@@ -255,12 +258,7 @@
 
 #if 0
-    // Or you can set them individually
-    OPTION_PARSE(options->zero,     config->arguments, "-zero",    Bool);
-    OPTION_PARSE(options->scale,    config->arguments, "-scale",   Bool);
-    OPTION_PARSE(options->darktime, config->arguments, "-exptime", Bool);
-#endif
-
     // Number of on/off images
     OPTION_PARSE(options->onOff, config->arguments, "-onoff", S32);
+#endif
 
     // Masking options
@@ -268,4 +266,49 @@
     options->badMask = pmConfigMask("BAD", config);
 
+    if (options->dark) {
+        psMetadata *ordinates = psMetadataLookupMetadata(NULL, recipe, "DARK.ORDINATES"); // Ordinates info
+        options->darkOrdinates = psArrayAllocEmpty(psListLength(ordinates->list));
+
+        psMetadataIterator *iter = psMetadataIteratorAlloc(ordinates, PS_LIST_HEAD, NULL); // Iterator
+        psMetadataItem *item;           // Item from iteration
+        while ((item = psMetadataGetAndIncrement(iter))) {
+            int order = 0;              // Polynomial order
+            bool scale = false;         // Scale values?
+            float min = NAN, max = NAN; // Minimum and maximum values for scaling
+            switch (item->type) {
+              case PS_TYPE_S32:
+                order = item->data.S32;
+                break;
+              case PS_DATA_METADATA:
+                order = psMetadataLookupS32(NULL, item->data.md, "ORDER");
+                bool mdok;                  // Status of MD lookup
+                scale = psMetadataLookupBool(&mdok, item->data.md, "SCALE");
+                min = psMetadataLookupF32(&mdok, item->data.md, "MIN");
+                max = psMetadataLookupF32(&mdok, item->data.md, "MAX");
+                break;
+              default:
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        "Type of DARK.ORDINATES entry %s (%x) is not METADATA or S32",
+                        item->name, item->type);
+                psFree(options);
+                return false;
+            }
+            if (order <= 0) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true, "ORDER not positive (%d) for DARK.ORDINATES %s",
+                        order, item->name);
+                psFree(options);
+                return false;
+            }
+
+            pmDarkOrdinate *ord = pmDarkOrdinateAlloc(item->name, order);
+            ord->scale = scale;
+            ord->min = min;
+            ord->max = max;
+            psArrayAdd(options->darkOrdinates, options->darkOrdinates->n, ord);
+            psFree(ord);
+        }
+        psFree(iter);
+    }
+
     return options;
 }
Index: /trunk/ppMerge/src/ppMergeOptions.h
===================================================================
--- /trunk/ppMerge/src/ppMergeOptions.h	(revision 16841)
+++ /trunk/ppMerge/src/ppMergeOptions.h	(revision 16842)
@@ -21,5 +21,5 @@
     bool zero;                          // Subtract background before combining?
     bool scale;                         // Scale by the background before combining?
-    bool darktime;                      // Normalise by the dark time (time since flush)?
+    bool dark;                          // Generate dark?
     bool fringe;                        // Make fringe measurements?
     bool shutter;                       // Generate shutter correction?
@@ -37,6 +37,6 @@
     float maskSuspect;                  // Threshold for identifying suspect pixels
     float maskBad;                      // Threshold for identifying bad pixels
-    bool statsByChip;			// measure statistics for masking by chip or readout?
-    pmMaskIdentifyMode maskMode;	// how to set the limit based on the threshold value above?
+    bool statsByChip;                   // measure statistics for masking by chip or readout?
+    pmMaskIdentifyMode maskMode;        // how to set the limit based on the threshold value above?
     ppOnOff onOff;                      // On/off pairs?
     pmCombineParams *combine;           // Combination parameters
@@ -44,4 +44,5 @@
     psMaskType badMask;                 // Mask value for bad (low) pixels
     int growPixels;
+    psArray *darkOrdinates;             // Ordinates for dark combination
 } ppMergeOptions;
 
Index: /trunk/ppMerge/src/ppMergeScaleZero.c
===================================================================
--- /trunk/ppMerge/src/ppMergeScaleZero.c	(revision 16841)
+++ /trunk/ppMerge/src/ppMergeScaleZero.c	(revision 16842)
@@ -25,5 +25,5 @@
     assert(config);
 
-    if (!options->scale && !options->zero && !options->darktime && !options->shutter) {
+    if (!options->scale && !options->zero && !options->shutter) {
         return true;                    // We did everything we were asked for
     }
@@ -151,10 +151,6 @@
     psStats *bgStats = psStatsAlloc(options->mean); // Statistic to measure the background
     psVector *gains = NULL;             // The gains for each cell
-    psImage *darktime = NULL;           // The dark time for each integration of each cell
     if (options->scale) {
         gains = psVectorAlloc(data->numCells, PS_TYPE_F32);
-    }
-    if (options->darktime) {
-        darktime = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32);
     }
 
@@ -187,42 +183,4 @@
                 if (!pmCellReadHeader(cell, inFile)) {
                     continue;
-                }
-
-                // Normalising by the exposure time
-                if (options->darktime) {
-                    darktime->data.F32[i][cellNum] = psMetadataLookupF32(NULL, cell->concepts,
-                                                                         "CELL.DARKTIME");
-                    if (isnan(darktime->data.F32[i][cellNum])) {
-                        psWarning("CELL.DARKTIME for file %s chip %d cell %d is not set.\n", name, j, k);
-                        status = false;
-                    } else {
-                        view->chip = j;
-                        view->cell = k;
-
-			// This step applies the dark exptime / background relationship: F =
-			// polymomial(exptime).  Below, the input images are scaled by the
-			// output of this relationship.
-
-			// For devices with linear dark and no residual bias, this relationship
-			// is not defined in the configuration system, and the transformation
-			// is defined (when loaded by the concepts) to be F = exptime.  Thus,
-			// in this case, the resulting dark image consists of counts/sec.
-
-			// For devices with a different relationship, the transformation yields
-			// the expected number of counts in the given exposure, based on the
-			// recorded exptime.  Thus, in this case, the resulting dark image
-			// should have a median value of 1.0.
-
-			// note that these corrections must be applied differently when used to
-			// correct a science image.  
-
-                        darktime->data.F32[i][cellNum] = pmFPADarkNorm(fpa, view,
-                                                                       darktime->data.F32[i][cellNum]);
-                        if (isnan(darktime->data.F32[i][cellNum])) {
-                            psWarning("Cannot get dark normalisation for file %s chip %d cell %d.\n",
-                                      name, j, k);
-                            status = false;
-                        }
-                    }
                 }
 
@@ -355,13 +313,4 @@
     }
 
-    if (options->darktime) {
-        if (!options->scale) {
-            // Copy over the exposure times
-            *scales = psImageCopy(*scales, darktime, PS_TYPE_F32);
-        } else {
-            *scales = (psImage*)psBinaryOp(*scales, *scales, "*", darktime);
-        }
-    }
-
     if (options->zero) {
         if (!*zeros) {
