Index: /branches/ipp-magic-v0/ppSub/src/ppSubReadoutUpdate.c
===================================================================
--- /branches/ipp-magic-v0/ppSub/src/ppSubReadoutUpdate.c	(revision 21397)
+++ /branches/ipp-magic-v0/ppSub/src/ppSubReadoutUpdate.c	(revision 21397)
@@ -0,0 +1,90 @@
+/** @file ppSubReadoutUpdate.c
+ *
+ *  @brief
+ *
+ *  @ingroup ppSub
+ *
+ *  @author IfA
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-07 00:15:00 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+#include "ppSub.h"
+
+/**
+ * Renormalize, update headers and generate JPEGs
+ */
+bool ppSubReadoutUpdate (pmConfig *config, const pmFPAview *view) {
+
+    bool mdok = false;
+
+    // Look up recipe values
+    psMetadata *recipe = psMetadataLookupMetadata(&mdok, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
+    psAssert(recipe, "We checked this earlier, so it should be here.");
+
+    // select the output readout
+    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT");
+
+    // Renormalising for pixels, because that's what magic desires
+    if (!ppSubReadoutRenormPixels (config, recipe, outRO)) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, false, "failure in renormalization");
+        return false;
+    }
+
+    // select the output FPA and HDU to get the output header
+    pmFPAfile *outFile = psMetadataLookupPtr (&mdok, config->files, "PPSUB.OUTPUT");
+    pmFPA *outFPA = outFile->fpa;
+    pmHDU *outHDU = outFPA->hdu;
+
+    // Add additional data to the header
+    pmFPAfile *refFile = psMetadataLookupPtr(NULL, config->files, "PPSUB.REF"); // Reference file
+    pmFPAfile *inFile = psMetadataLookupPtr(NULL, config->files, "PPSUB.INPUT"); // Input file
+    psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.REFERENCE", 0,
+                     "Subtraction reference", refFile->filename);
+    psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.INPUT", 0,
+                     "Subtraction input", inFile->filename);
+
+    // Generate binned JPEGs
+    {
+        psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask for bad pixels
+
+        int bin1 = psMetadataLookupS32(NULL, recipe, "BIN1"); // First binning level
+        int bin2 = psMetadataLookupS32(NULL, recipe, "BIN2"); // Second binning level
+
+        // Target cells
+        pmCell *cell1 = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT.JPEG1");
+        pmCell *cell2 = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT.JPEG2");
+
+        pmReadout *ro1 = pmReadoutAlloc(cell1);
+        pmReadout *ro2 = pmReadoutAlloc(cell2); // Binned readouts
+        if (!pmReadoutRebin(ro1, outRO, maskBad, bin1, bin1)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to bin output (1st binning)");
+            psFree(ro1);
+            psFree(ro2);
+            return false;
+        }
+        if (!pmReadoutRebin(ro2, ro1, 0, bin2, bin2)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to bin output (2nd binning)");
+            psFree(ro1);
+            psFree(ro2);
+            return false;
+        }
+        psFree(ro1);
+        psFree(ro2);
+    }
+
+#ifdef TESTING
+    // Significance image
+    {
+        psImage *sig = (psImage*)psBinaryOp(NULL, outRO->image, "*", outRO->image);
+        psBinaryOp(sig, sig, "/", outRO->variance);
+        psFits *fits = psFitsOpen("significance.fits", "w");
+        psFitsWriteImage(fits, NULL, sig, 0, NULL);
+        psFitsClose(fits);
+        psFree(sig);
+    }
+#endif
+
+    return true;
+}
