Index: trunk/ppBackground/src/ppBackgroundStackLoop.c
===================================================================
--- trunk/ppBackground/src/ppBackgroundStackLoop.c	(revision 36580)
+++ trunk/ppBackground/src/ppBackgroundStackLoop.c	(revision 36582)
@@ -13,5 +13,5 @@
     )
 {
-  //    pmConfig *config = data->config;                                        // Configuration data
+  pmConfig *config = data->config;                                        // Configuration data
     int i;
     //
@@ -63,10 +63,114 @@
     // Loop over the input images, and apply the models to construct the restored versions.
 
-    for (i = 0; i < data->stacks->n; i++) {
+    for (i = 0; i < data->stack_data->n; i++) {
+      pmFPAfile *stack = data->stack_data->data[i];
+      pmFPAview *view = pmFPAviewAlloc(0);
       // Define output image
-      // Calculate model for each pixel of output
-      // Close output image
+      pmFPAfile *stack_model = pmFPAfileDefineOutput(config,stack->fpa,"PPBACKGROUND.STACK.MODEL");
+
+      if (!stack_model) {
+	psError(psErrorCodeLast(), false, "Unable to generate output model");
+	return (false);
+      }
+      
+      pmFPAfile *stack_corr  = pmFPAfileDefineOutput(config,stack->fpa,"PPBACKGROUND.STACK.OUTPUT");
+      if (!stack_corr) {
+	psError(psErrorCodeLast(), false, "Unable to generate output result");
+	return (false);
+      }
+      stack_model->save = true;
+      stack_corr->save = true;
+
+      // Iterate over the images.
+      pmChip *chip;
+      while ((chip = pmFPAviewNextChip(view, stack->fpa, 1))) {
+	if (!chip->process || !chip->file_exists) {
+	  continue;
+	}
+
+	if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+	  psError(psErrorCodeLast(), false, "load failure for Chip");
+	  return(false);
+	}
+
+	pmCell *cell;
+	
+	while ((cell = pmFPAviewNextCell(view, stack->fpa, 1)) != NULL) {
+	  psLogMsg ("ppImageLoop", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+	  if (!cell->process || !cell->file_exists) {
+	    continue;
+	  }
+	  if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+	    psError(psErrorCodeLast(), false, "load failure for Cell");
+	    return(false);
+	  }
+	  if (cell->readouts->n > 1) {
+	    psWarning ("Skipping Video Cell for ppImageDetrendReadout");
+	    continue;
+	  }
+
+	  // process each of the readouts
+	  pmReadout *readout;         // Readout from cell
+	  while ((readout = pmFPAviewNextReadout (view, stack->fpa, 1)) != NULL) {
+	    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+	      	psError(psErrorCodeLast(), false, "load failure for Readout");
+		return(false);
+	    }
+	    if (!readout->data_exists) {
+	      continue;
+	    }
+
+	    pmReadout *model = pmFPAfileThisReadout(config->files,view,"PPBACKGROUND.STACK.MODEL");
+	    pmReadout *corr  = pmFPAfileThisReadout(config->files,view,"PPBACKGROUND.STACK.OUTPUT");
+
+	    psPlane *pix = psPlaneAlloc();   // Pixel coordinates on chip
+	    psPlane *fp = psPlaneAlloc();    // Focal plane coordinates
+	    psPlane *tp = psPlaneAlloc();    // Tangent plane coordinates
+	    
+	    int x,y;
+	    for (y = 0; y < readout->image->numRows; y++) {
+	      for (x = 0; x < readout->image->numCols; x++) {
+		// Calculate model for each pixel of output
+		psPlaneTransformApply(fp, chip->toFPA, pix);
+		psPlaneTransformApply(tp, stack->fpa->toTPA, fp);
+		
+		model->image->data.F32[y][x] = psImageMapEval(data->modelMap,tp->x,tp->y);
+		corr->image->data.F32[y][x] = readout->image->data.F32[y][x] + model->image->data.F32[y][x];
+	      }
+	    }
+	    psFree(pix);
+	    psFree(fp);
+	    psFree(tp);
+	  } // Close readout
+
+	  // Close output image
+	  // Close cells (XXX shouldn't pmFPAfileClose iterate down as needed?)
+	  view->cell = -1;
+	  while ((cell = pmFPAviewNextCell(view, stack->fpa, 1)) != NULL) {
+	    if (!cell->process || !cell->file_exists) {
+	      continue;
+	    }
+	    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+	      	psError(psErrorCodeLast(), false, "save failure for Cell");
+		return(false);
+	    }
+	  }
+	} // Close Cell
+	
+        // Close chip
+	if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+	  psError(psErrorCodeLast(), false, "save failure for Chip");
+	  return(false);
+	}
+      } // Close chip.
+      // Output and Close FPA
+      if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+	psError(psErrorCodeLast(), false, "save failure for FPA");
+	return(false);
+      }
+      psFree(view);
     }      
-
+		
+    
     return(true);
 }
