Index: trunk/ppImage/src/ppImageReplaceBackground.c
===================================================================
--- trunk/ppImage/src/ppImageReplaceBackground.c	(revision 20444)
+++ trunk/ppImage/src/ppImageReplaceBackground.c	(revision 20772)
@@ -20,12 +20,4 @@
     if (!status) {
         psError(PS_ERR_UNEXPECTED_NULL, true, "PPIMAGE.CHIP file is not defined");
-        return false;
-    }
-
-    // The background model file may be defined, though the model hasn't been built
-    // If so, we will build it below.
-    pmFPAfile *modelFile = psMetadataLookupPtr(&status, config->files, "PSPHOT.BACKMDL"); // Background model
-    if (!status) {
-        psError(PS_ERR_UNEXPECTED_NULL, true, "PSPHOT.BACKMDL file is not defined");
         return false;
     }
@@ -75,24 +67,75 @@
     psImage *image = ro->image, *mask = ro->mask; // Image and mask of interest
 
+    // View corresponding to this readout
+    pmFPAview roView = *view;
+    roView.cell = roView.readout = 0;
 
-    pmFPAview roView = *view;           // View to readout
-    roView.cell = roView.readout = 0;
-    pmReadout *modelRO = pmFPAviewThisReadout(&roView, modelFile->fpa); // Background model
-    if (!modelRO) {
-        // Create the background model
+    // If the background model file has not been defined, psphotModelBackground will generate it
+    pmReadout *modelRO = NULL;
+    pmFPAfile *modelFile = psMetadataLookupPtr(&status, config->files, "PSPHOT.BACKMDL"); // Background model
+    if (modelFile) {
+	modelRO = pmFPAviewThisReadout(&roView, modelFile->fpa); // Background model
+    }
+
+    // the background model has not been defined, or at least not generated
+    if (!modelFile || !modelRO) {
         if (!psphotModelBackground(config, &roView, "PPIMAGE.CHIP")) {
             psError(PS_ERR_UNKNOWN, false, "Unable to model background");
             return false;
         }
-        modelRO = (modelFile->mode == PM_FPA_MODE_INTERNAL) ? modelFile->readout :
-                   pmFPAviewThisReadout(&roView, modelFile->fpa);
-        if (!modelRO) {
+	// the model file should now at least be defined
+	modelFile = psMetadataLookupPtr(&status, config->files, "PSPHOT.BACKMDL"); // Background model
+	if (!modelFile) {
+            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to define background model I/O file");
+            return false;
+        }
+	// now grab the readout from the correct location:
+        if (modelFile->mode == PM_FPA_MODE_INTERNAL) {
+	    modelRO = modelFile->readout;
+	} else {
+	    modelRO = pmFPAviewThisReadout(&roView, modelFile->fpa);
+	}        
+	if (!modelRO) {
             psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find background model");
             return false;
         }
     }
-    psImageBinning *binning = psMetadataLookupPtr(&status, psphotRecipe,
-                                                  "PSPHOT.BACKGROUND.BINNING"); // Binning for model
-    psImage *modelImage = modelRO->image; // Background model
+    psImageBinning *binning = psMetadataLookupPtr(&status, psphotRecipe, "PSPHOT.BACKGROUND.BINNING"); // Binning for model
+    if (!binning) {
+	psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find background binning");
+	return false;
+    }
+
+# define USE_UNBIN 1
+# if (USE_UNBIN)
+    // select background pixels, from output background file, or create
+    pmReadout *background = NULL;
+    pmFPAfile *backfile = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKGND");
+    if (backfile) {
+        // we are using PSPHOT.BACKGND as an I/O file: select readout or create
+        if (backfile->mode == PM_FPA_MODE_INTERNAL) {
+            background = backfile->readout;
+        } else {
+            background = pmFPAviewThisReadout (&roView, backfile->fpa);
+        }
+        if (background == NULL) {
+            // readout does not yet exist: create from input
+            pmFPAfileCopyStructureView (backfile->fpa, input->fpa, 1, 1, &roView);
+            background = pmFPAviewThisReadout (&roView, backfile->fpa);
+            if ((image->numCols != background->image->numCols) || (image->numRows != background->image->numRows)) {
+                psError (PSPHOT_ERR_PROG, true, "inconsistent sizes for background dimensions");
+                return false;
+            }
+        }
+    } else {
+        background = pmFPAfileDefineInternal (config->files, "PSPHOT.BACKGND", image->numCols, image->numRows, PS_TYPE_F32);
+    }
+    psF32 **backData = background->image->data.F32;
+
+    // linear interpolation to full-scale
+    if (!psImageUnbin (background->image, modelRO->image, binning)) {
+        psError (PSPHOT_ERR_PROG, true, "inconsistent sizes for unbinning");
+        return false;
+    }
 
     // Do the background subtraction
@@ -103,5 +146,5 @@
                 image->data.F32[y][x] = 0.0;
             } else {
-                float value = psImageUnbinPixel_V2(x, y, modelImage, binning); // Background value
+                float value = backData[y][x];
                 if (!isfinite(value)) {
                     image->data.F32[y][x] = NAN;
@@ -113,7 +156,27 @@
         }
     }
-
-    pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL");
-    pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL.STDEV");
+# else
+    // Do the background subtraction
+    int numCols = image->numCols, numRows = image->numRows; // Size of image
+    for (int y = 0; y < numRows; y++) {
+        for (int x = 0; x < numCols; x++) {
+            if (mask && mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) {
+                image->data.F32[y][x] = 0.0;
+            } else {
+                float value = psImageUnbinPixel(x + 0.5, y + 0.5, modelRO->image, binning); // Background value
+                if (!isfinite(value)) {
+                    image->data.F32[y][x] = NAN;
+                    mask->data.PS_TYPE_MASK_DATA[y][x] |= options->badMask;
+                } else {
+                    image->data.F32[y][x] -= value;
+                }
+            }
+        }
+    }
+# endif
+    
+    // XXX should these really be here?? (probably not...)
+    // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL"); 
+    // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL.STDEV");
 
     return true;
