Index: branches/simmosaic_branches/psphot/src/psphotMaskReadout.c
===================================================================
--- branches/simmosaic_branches/psphot/src/psphotMaskReadout.c	(revision 24860)
+++ branches/simmosaic_branches/psphot/src/psphotMaskReadout.c	(revision 27839)
@@ -1,12 +1,40 @@
 # include "psphotInternal.h"
 
+bool psphotSetMaskAndVariance (pmConfig *config, const pmFPAview *view) {
+
+    bool status = false;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
+    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
+
+    // loop over the available readouts
+    for (int i = 0; i < num; i++) {
+
+	// Generate the mask and weight images, including the user-defined analysis region of interest
+	if (!psphotSetMaskAndVarianceReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed to generate mask for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
 // generate mask and variance if not defined, additional mask for restricted subregion
-bool psphotSetMaskAndVariance (pmConfig *config, pmReadout *readout, psMetadata *recipe) {
+bool psphotSetMaskAndVarianceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) {
 
     bool status;
 
-    // ** Interpret the mask values:
-    // XXX drop the write to recipe and move config into psphotRoughClass?
-    // XXX alternatively, define a function to set the psphot recipe masks
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", index); // File of interest
+    psAssert (file, "missing file?");
+
+    // find the currently selected readout
+    pmReadout  *readout = pmFPAviewThisReadout (view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    // save maskSat and maskBad on the psphot recipe (mostly for psphotRoughClass)
     psImageMaskType maskSat  = pmConfigMaskGet("SAT", config); // Mask value for saturated pixels
     psMetadataAddImageMask (recipe, PS_LIST_TAIL, "MASK.SAT", PS_META_REPLACE, "user-defined mask", maskSat);
@@ -14,5 +42,5 @@
     psImageMaskType maskBad  = pmConfigMaskGet("LOW", config); // Mask value for low pixels
     if (!maskBad) {
-        // XXX: for backward compatability look up old name
+        // for backward compatability look up old name
         maskBad  = pmConfigMaskGet("BAD", config);
     }
@@ -33,13 +61,17 @@
     }
 
+    bool softenVariance = psMetadataLookupBool (&status, recipe, "SOFTEN.VARIANCE");
+    float softenFraction = psMetadataLookupF32 (&status, recipe, "SOFTEN.VARIANCE.FRACTION");
+
     // make this an option via the recipe
-    if (0) {
+    if (softenVariance) {
       psImage *im = readout->image;
       psImage *wt = readout->variance;
-      psImage *mk = readout->mask;
       for (int j = 0; j < im->numRows; j++) {
         for (int i = 0; i < im->numCols; i++) {
-          if (isfinite(im->data.F32[j][i]) && isfinite(wt->data.F32[j][i])) continue;
-          mk->data.PS_TYPE_IMAGE_MASK_DATA[j][i] |= maskBad;
+	    if (!isfinite(im->data.F32[j][i])) continue;
+	    if (!isfinite(wt->data.F32[j][i])) continue;
+	    float sysError = softenFraction * im->data.F32[j][i];
+	    wt->data.F32[j][i] += PS_SQR(sysError);
         }
       }
@@ -69,4 +101,7 @@
     }
 
+    // display the image, weight, mask (ch 1,2,3)
+    psphotVisualShowImage (readout);
+
     return true;
 }
