Index: /branches/eam_branch_20080706/pswarp/src/Makefile.am
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/Makefile.am	(revision 18512)
+++ /branches/eam_branch_20080706/pswarp/src/Makefile.am	(revision 18513)
@@ -15,4 +15,5 @@
 	pswarpParseCamera.c		\
 	pswarpPixelFraction.c		\
+	pswarpSetMaskBits.c		\
 	pswarpTransformReadout_Opt.c	\
 	pswarpVersion.c            
Index: /branches/eam_branch_20080706/pswarp/src/pswarp.h
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/pswarp.h	(revision 18512)
+++ /branches/eam_branch_20080706/pswarp/src/pswarp.h	(revision 18513)
@@ -38,4 +38,5 @@
 pmConfig *pswarpArguments (int argc, char **argv);
 bool pswarpOptions(pmConfig *config);
+bool pswarpSetMaskBits (pmConfig *config);
 bool pswarpParseCamera (pmConfig *config);
 bool pswarpDefine (pmConfig *config);
Index: /branches/eam_branch_20080706/pswarp/src/pswarpArguments.c
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/pswarpArguments.c	(revision 18512)
+++ /branches/eam_branch_20080706/pswarp/src/pswarpArguments.c	(revision 18513)
@@ -109,28 +109,4 @@
     }
 
-    // Get mask parameters
-    psMaskType maskIn, maskPoor, maskBad; // Mask values for input, "poor" and "bad" pixels
-
-    psString maskNames = psMetadataLookupStr(&status, recipe, "MASK.IN");
-    if (!status) {
-        maskIn = 0x00;
-        psWarning("MASK.IN is not set in the %s recipe --- defaulting to %x.", PSWARP_RECIPE, maskIn);
-    }
-    maskIn = pmConfigMask(maskNames, config); // Mask for input data
-
-    maskNames = psMetadataLookupStr(&status, recipe, "MASK.POOR");
-    if (!status) {
-        maskPoor = 0x00;
-        psWarning("MASK.POOR is not set in the %s recipe --- defaulting to %x.", PSWARP_RECIPE, maskPoor);
-    }
-    maskPoor = pmConfigMask(maskNames, config); // Mask for "poor" warped data
-
-    maskNames = psMetadataLookupStr(&status, recipe, "MASK.BAD");
-    if (!status) {
-        maskBad = 0x00;
-        psWarning("MASK.BAD is not set in the %s recipe --- defaulting to %x.", PSWARP_RECIPE, maskBad);
-    }
-    maskBad = pmConfigMask(maskNames, config); // Mask for bad warped data
-
     float poorFrac = psMetadataLookupF32(&status, recipe, "POOR.FRAC"); // Frac of bad flux for a "poor"
     if (!status) {
@@ -152,10 +128,4 @@
     psMetadataAddS32(config->arguments, PS_LIST_TAIL, "INTERPOLATION.MODE", 0,
                      "Interpolation mode", interpolationMode);
-    psMetadataAddU8(config->arguments, PS_LIST_TAIL, "MASK.IN", 0,
-                    "Mask for input data", maskIn);
-    psMetadataAddU8(config->arguments, PS_LIST_TAIL, "MASK.POOR", 0,
-                    "Mask for poor warped data", maskPoor);
-    psMetadataAddU8(config->arguments, PS_LIST_TAIL, "MASK.BAD", 0,
-                    "Mask for bad warped data", maskBad);
     psMetadataAddF32(config->arguments, PS_LIST_TAIL, "POOR.FRAC", 0,
                      "Fraction of bad flux for a pixel to be marked as poor", poorFrac);
Index: /branches/eam_branch_20080706/pswarp/src/pswarpLoop.c
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/pswarpLoop.c	(revision 18512)
+++ /branches/eam_branch_20080706/pswarp/src/pswarpLoop.c	(revision 18513)
@@ -64,7 +64,16 @@
 bool pswarpLoop(pmConfig *config)
 {
-
-    psMaskType maskPoor = psMetadataLookupU8(NULL, config->arguments, "MASK.POOR"); // Mask for "poor" data
-    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Mask for bad data
+    bool status; 
+
+    // load the recipe
+    psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSWARP_RECIPE);
+        return false;
+    }
+
+    // output mask bits
+    psMaskType maskValue = psMetadataLookupU8(&status, recipe, "MASK.OUTPUT"); 
+    psAssert (status, "MASK.OUTPUT was not defined");
 
     // select the input data sources
@@ -333,5 +342,5 @@
     // Perform statistics on the output image
     if (stats) {
-        if (!ppStatsFPA(stats, output->parent->parent->parent, view, maskBad | maskPoor, config)) {
+        if (!ppStatsFPA(stats, output->parent->parent->parent, view, maskValue, config)) {
             psWarning("Unable to perform statistics on warped image.");
         }
Index: /branches/eam_branch_20080706/pswarp/src/pswarpParseCamera.c
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/pswarpParseCamera.c	(revision 18512)
+++ /branches/eam_branch_20080706/pswarp/src/pswarpParseCamera.c	(revision 18513)
@@ -37,4 +37,10 @@
     if (!inMask) {
         psLogMsg ("pswarp", 3, "no mask supplied\n");
+    }
+    
+    // loading the mask here should have invoked pmConfigMaskReadHeader()
+    if (!pswarpSetMaskBits (config)) {
+        psError(PS_ERR_IO, false, "failed to set mask bits");
+        return NULL;
     }
 
Index: /branches/eam_branch_20080706/pswarp/src/pswarpPixelFraction.c
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/pswarpPixelFraction.c	(revision 18512)
+++ /branches/eam_branch_20080706/pswarp/src/pswarpPixelFraction.c	(revision 18513)
@@ -28,8 +28,18 @@
     PS_ASSERT_METADATA_NON_NULL(config->arguments, false);
 
+    bool status; 
+
     float minFrac = psMetadataLookupF32(NULL, config->arguments, "ACCEPT.FRAC"); // Minimum fraction
-    psMaskType maskPoor = psMetadataLookupU8(NULL, config->arguments, "MASK.POOR"); // Mask for "poor" data
-    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Mask for bad data
-    psMaskType maskVal = maskPoor | maskBad; // Mask to apply
+
+    // load the recipe
+    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSWARP_RECIPE);
+        return false;
+    }
+
+    // output mask bits
+    psMaskType maskValue = psMetadataLookupU8(&status, recipe, "MASK.OUTPUT"); 
+    psAssert (status, "MASK.OUTPUT was not defined");
 
     psImage *image = readout->image;    // Image of interest
@@ -45,5 +55,5 @@
     for (int y = 0; y < numRows; y++) {
         for (int x = 0; x < numCols; x++) {
-            if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) {
+            if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskValue) {
                 numBad++;
             } else {
Index: /branches/eam_branch_20080706/pswarp/src/pswarpSetMaskBits.c
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/pswarpSetMaskBits.c	(revision 18513)
+++ /branches/eam_branch_20080706/pswarp/src/pswarpSetMaskBits.c	(revision 18513)
@@ -0,0 +1,83 @@
+# include "pswarp.h"
+
+// This function is called by the stand-alone pswarp program to set the mask values in the
+// config file.  It sets the named mask values MASK.PSPHOT and MARK.PSPHOT in the PSPHOT
+// recipe.  Functions or programs which call psphotReadout as a library function must set these
+// named mask values in the PSPHOT recipe on their own.  This function should only be called
+// after the first header of the input mask image has been loaded and the named mask bits
+// updated in the config metadata.
+
+bool pswarpSetMaskBits (pmConfig *config) {
+
+    psMaskType maskIn = 0x00;			// mask for the input image
+    psMaskType markIn = 0x00;			// mark for the input image
+    psMaskType maskOut = 0x00;			// mask for the output image
+    psMaskType markOut = 0x00;			// mark for the output image
+
+    // this function sets the required single-image mask bits
+    if (!pmConfigMaskSetBits (&maskIn, &markIn, config)) {
+	psError (PS_ERR_UNKNOWN, true, "Unable to define the mask bit values");
+	return false;
+    }
+
+    // mask for non-linear flat regions (default to DETECTOR if not defined)
+    psMaskType badMask = pmConfigMaskGet("BAD.WARP", config); 
+    if (!badMask) {
+	badMask = 0x01;
+	pmConfigMaskSet (config, "BAD.WARP", badMask);
+    }
+    maskOut |= badMask;
+
+    // mask for non-linear flat regions (default to DETECTOR if not defined)
+    psMaskType poorMask = pmConfigMaskGet("POOR.WARP", config); 
+    if (!poorMask) {
+	poorMask = 0x02;
+	pmConfigMaskSet (config, "POOR.WARP", poorMask);
+    }
+    maskOut |= poorMask;
+
+    // search for an unset bit to use for MARK:
+    markOut = 0x80;
+
+    int nBits = sizeof(psMaskType) * 8;
+    for (int i = 0; !markOut && (i < nBits); i++) {
+	if (maskOut & markOut) {
+	    markOut >>= 1;
+	} else {
+	    markOut = markOut;
+	}
+    }
+
+    if (!markOut) {
+	psError (PS_ERR_UNKNOWN, true, "Unable to define the MARK bit mask: all bits taken!");
+	return false;
+    }
+
+    // update the pswarp recipe
+    psMetadata *warpRecipe = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
+    if (!warpRecipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSWARP_RECIPE);
+        return false;
+    }
+
+    // set maskOut and markOut in the psphot recipe
+    // NOTE: psphot works on the output images, not input images, so set the MARK and MASK correctly here
+    psMetadataAddU8 (warpRecipe, PS_LIST_TAIL, "MASK.INPUT",  PS_META_REPLACE, "user-defined mask", maskIn);
+    psMetadataAddU8 (warpRecipe, PS_LIST_TAIL, "MARK.INPUT",  PS_META_REPLACE, "user-defined mask", markIn);
+    psMetadataAddU8 (warpRecipe, PS_LIST_TAIL, "MASK.OUTPUT", PS_META_REPLACE, "user-defined mask", maskOut);
+    psMetadataAddU8 (warpRecipe, PS_LIST_TAIL, "MARK.OUTPUT", PS_META_REPLACE, "user-defined mask", markOut);
+
+    // update the psphot recipe
+    psMetadata *psphotRecipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
+    if (!psphotRecipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);
+        return false;
+    }
+
+    // set maskOut and markOut in the psphot recipe
+    // NOTE: psphot works on the output images, not input images, so set the MARK and MASK correctly here
+    psMetadataAddU8 (psphotRecipe, PS_LIST_TAIL, "MARK.PSPHOT", PS_META_REPLACE, "user-defined mask", markOut);
+    psMetadataAddU8 (psphotRecipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask", maskOut);
+
+    return true;
+}
Index: /branches/eam_branch_20080706/pswarp/src/pswarpTransformReadout_Opt.c
===================================================================
--- /branches/eam_branch_20080706/pswarp/src/pswarpTransformReadout_Opt.c	(revision 18512)
+++ /branches/eam_branch_20080706/pswarp/src/pswarpTransformReadout_Opt.c	(revision 18513)
@@ -17,7 +17,17 @@
     psImageInterpolateMode interpolationMode = psMetadataLookupS32(NULL, config->arguments,
                                                                    "INTERPOLATION.MODE");
-    psMaskType maskIn = psMetadataLookupU8(NULL, config->arguments, "MASK.IN"); // Mask for input data
-    psMaskType maskPoor = psMetadataLookupU8(NULL, config->arguments, "MASK.POOR"); // Mask for "poor" data
-    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Mask for bad data
+    // load the recipe
+    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSWARP_RECIPE);
+        return false;
+    }
+
+    // output mask bits
+    psMaskType maskIn   = psMetadataLookupU8(&mdok, recipe, "MASK.INPUT"); 
+    psMaskType maskPoor = pmConfigMaskGet("POOR.WARP", config); 
+    psMaskType maskBad  = pmConfigMaskGet("BAD.WARP", config); 
+    psAssert (mdok, "MASK.INPUT was not defined");
+
     float poorFrac = psMetadataLookupF32(NULL, config->arguments, "POOR.FRAC"); // Flux fraction for "poor"
 
@@ -62,5 +72,5 @@
 
     // Interpolation options
-    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(interpolationMode, inImage,
+    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(interpolationMode, inImage, 
                                                                        inVar, inMask, maskIn, NAN, NAN,
                                                                        maskBad, maskPoor, poorFrac);
