Index: /trunk/ppMerge/src/ppMergeBackground.c
===================================================================
--- /trunk/ppMerge/src/ppMergeBackground.c	(revision 7001)
+++ /trunk/ppMerge/src/ppMergeBackground.c	(revision 7001)
@@ -0,0 +1,132 @@
+#include <stdio.h>
+#include <assert.h>
+#include <pslib.h>
+#include <psmodules.h>
+
+#include "ppMergeBackground.h"
+
+// Extract a particular statistic from the stats
+static inline double getStat(const psStats *stats, // Statistics structure
+                             psStatsOptions option // Statistic option to return
+    )
+{
+    switch (option) {
+      case PS_STAT_SAMPLE_MEAN:
+        return stats->sampleMean;
+      case PS_STAT_SAMPLE_MEDIAN:
+        return stats->sampleMedian;
+      case PS_STAT_ROBUST_MEDIAN:
+        return stats->robustMedian;
+      case PS_STAT_FITTED_MEAN:
+        return stats->fittedMean;
+      case PS_STAT_CLIPPED_MEAN:
+        return stats->clippedMean;
+      default:
+        psAbort(__func__, "Invalid statistics option: %x\n", option);
+    }
+    return NAN;                         // Token return
+}
+
+
+// Get the background for each chip of each input
+psImage *ppMergeBackground(const ppMergeOptions *options, // The options
+                           const pmConfig *config // The configuration
+    )
+{
+    assert(config->camera);             // Need the camera configuration
+    int numCells = 0;                   // Number of cells in the model FPA
+    {
+        // Count the cells
+        pmFPA *fpa = pmFPAConstruct(config->camera); // The FPA
+        psArray *chips = fpa->chips;        // Array of chips
+        for (int i = 0; i < chips->n; i++) {
+            pmChip *chip = chips->data[i];  // Chip of interest
+            if (!chip) {
+                continue;
+            }
+            psArray *cells = chip->cells;   // Array of cells
+            for (int j = 0; j < cells->n; j++) {
+                pmCell *cell = cells->data[j];
+                if (cell) {
+                numCells++;
+                }
+            }
+        }
+        psFree(fpa);
+    }
+    psArray *filenames = psMetadataLookupPtr(NULL, config->arguments, "INPUT"); // The input file names
+    assert(filenames);                  // It should be here --- it's put here in ppMergeConfig
+
+    psImage *background = psImageAlloc(filenames->n, numCells, PS_TYPE_F64); // Background measurements
+    psImageInit(background, NAN);
+    psStats *bgStats = psStatsAlloc(options->background); // Statistic to measure the background
+
+    for (int i = 0; i < filenames->n; i++) {
+        psString name = filenames->data[i]; // The name of the file
+        if (!name || strlen(name) == 0) {
+            continue;
+        }
+        psFits *inFile = psFitsOpen(filenames->data[i], "r"); // The FITS file to read
+        if (!inFile) {
+            psErrorPrint(PS_ERR_IO, false, "Unable to open input file %s --- ignored.\n", name);
+            continue;
+        }
+        psMetadata *header = psFitsReadHeader(NULL, inFile); // The FITS (primary) header
+        psMetadata *format = pmConfigCameraFormatFromHeader(config, header); // The camera format
+        psFree(header);
+        if (!format) {
+            psErrorPrint(PS_ERR_IO, false, "Unable to identify camera format for input file %s --- "
+                         "ignored.\n", name);
+            continue;
+        }
+
+        pmFPA *fpa = pmFPAConstruct(config->camera); // The FPA
+        pmFPAview *view = pmFPAAddSourceFromHeader(fpa, phu, format); // View of the PHU
+        int cellNum = 0;                // Number of the cell
+        psArray *chips = fpa->chips;    // Array of chips
+        for (int i = 0; i < chips->n; i++) {
+            pmChip *chip = chips->data[i]; // The chip of interest
+            if (!chip) {
+                continue;
+            }
+            psArray *cells = chip->cells; // Array of cells
+            for (int j = 0; j < cells->n; j++) {
+                pmCell *cell = cells->data[j]; // The cell of interest
+                if (!cell) {
+                    continue;
+                }
+
+                if (!pmCellRead(cell, inFile, config->database)) {
+                    // Nothing here
+                    psFree(cell);
+                    cellNum++;
+                    continue;
+                }
+
+                if (cell->readouts->n > 1) {
+                    psLogMsg(__func__, PS_LOG_WARN, "File %s chip %d cell %d contains more than one readout "
+                             "--- ignoring all but the first.\n", name, i, j);
+                }
+
+                pmReadout *readout = cell->readouts->data[0]; // The readout of interest
+                psImage *image = readout->image; // The pixels of interest
+                if (!image) {
+                    psFree(cell);
+                    cellNum++;
+                    continue;
+                }
+
+                psImageStats(bgStats, image, readout->mask, options->maskVal);
+                background[i][cellNum++] = getStat(bgStats, options->background);
+                psFree(cell);
+            }
+            psFree(chip);
+        }
+        psFree(fpa);
+        psFree(view);
+        psFitsClose(inFile);
+    }
+    psFree(bgStats);
+
+    return background;
+}
Index: /trunk/ppMerge/src/ppMergeBackground.h
===================================================================
--- /trunk/ppMerge/src/ppMergeBackground.h	(revision 7001)
+++ /trunk/ppMerge/src/ppMergeBackground.h	(revision 7001)
@@ -0,0 +1,9 @@
+#ifndef PP_MERGE_BACKGROUND_H
+#define PP_MERGE_BACKGROUND_H
+
+// Get the background for each chip of each input
+psImage *ppMergeBackground(const ppMergeOptions *options, // The options
+                           const pmConfig *config // The configuration
+    );
+
+#endif
