Index: /trunk/ppMerge/src/ppMerge.c
===================================================================
--- /trunk/ppMerge/src/ppMerge.c	(revision 23462)
+++ /trunk/ppMerge/src/ppMerge.c	(revision 23463)
@@ -55,4 +55,5 @@
       case PPMERGE_TYPE_FLAT:
       case PPMERGE_TYPE_FRINGE:
+      case PPMERGE_TYPE_CTEMASK:
         if (!ppMergeScaleZero(config)) {
             psErrorStackPrint(stderr, "Error getting scale and zero-points.");
Index: /trunk/ppMerge/src/ppMerge.h
===================================================================
--- /trunk/ppMerge/src/ppMerge.h	(revision 23462)
+++ /trunk/ppMerge/src/ppMerge.h	(revision 23463)
@@ -40,4 +40,5 @@
     PPMERGE_TYPE_DARK,                  ///< (Multi-)Dark frame
     PPMERGE_TYPE_MASK,                  ///< Mask frame
+    PPMERGE_TYPE_CTEMASK,		///< CTE Mask based on flat variance
     PPMERGE_TYPE_SHUTTER,               ///< Shutter frame
     PPMERGE_TYPE_FLAT,                  ///< Flat-field frame (dome or sky)
Index: /trunk/ppMerge/src/ppMergeArguments.c
===================================================================
--- /trunk/ppMerge/src/ppMergeArguments.c	(revision 23462)
+++ /trunk/ppMerge/src/ppMergeArguments.c	(revision 23463)
@@ -170,4 +170,7 @@
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-fringe-ysmooth", 0, "Number of smoothing regions in y", 0);
 
+    /** CTEMASK construction parameters */
+    psMetadataAddF32(arguments, PS_LIST_TAIL, "-cte-min", 0, "min allowed value for good CTE", NAN);
+
     /** Shutter construction parameters */
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-shutter-size", 0, "Size for shutter measurement regions", 0);
@@ -268,4 +271,8 @@
       goto VALID;
     }
+    if (strcasecmp(typeStr, "CTEMASK") == 0) {
+      type = PPMERGE_TYPE_CTEMASK;
+      goto VALID;
+    }
     if (strcasecmp(typeStr, "MASK") == 0 ||
         strcasecmp(typeStr, "DARKMASK") == 0 ||
@@ -314,4 +321,7 @@
     VALUE_ARG_RECIPE_INT("-fringe-xsmooth", "FRINGE.XSMOOTH", S32, 0);
     VALUE_ARG_RECIPE_INT("-fringe-ysmooth", "FRINGE.YSMOOTH", S32, 0);
+
+    /** CTEMASK construction parameters */
+    VALUE_ARG_RECIPE_FLOAT("-cte-min",      "CTE.MIN",        F32);
 
     /** Shutter construction parameters */
Index: /trunk/ppMerge/src/ppMergeCamera.c
===================================================================
--- /trunk/ppMerge/src/ppMergeCamera.c	(revision 23462)
+++ /trunk/ppMerge/src/ppMergeCamera.c	(revision 23463)
@@ -326,4 +326,7 @@
         fileType = PM_FPA_FILE_MASK;
         break;
+      case PPMERGE_TYPE_CTEMASK:
+        fileType = PM_FPA_FILE_MASK;
+        break;
       case PPMERGE_TYPE_SHUTTER:
         fileType = PM_FPA_FILE_IMAGE;
Index: /trunk/ppMerge/src/ppMergeFiles.c
===================================================================
--- /trunk/ppMerge/src/ppMergeFiles.c	(revision 23462)
+++ /trunk/ppMerge/src/ppMergeFiles.c	(revision 23463)
@@ -209,4 +209,7 @@
         outSuffix = "MASK";
         break;
+      case PPMERGE_TYPE_CTEMASK:
+        outSuffix = "MASK";
+        break;
       case PPMERGE_TYPE_SHUTTER:
         outSuffix = "SHUTTER";
Index: /trunk/ppMerge/src/ppMergeLoop.c
===================================================================
--- /trunk/ppMerge/src/ppMergeLoop.c	(revision 23462)
+++ /trunk/ppMerge/src/ppMergeLoop.c	(revision 23463)
@@ -118,4 +118,5 @@
       case PPMERGE_TYPE_BIAS:
       case PPMERGE_TYPE_DARK:
+      case PPMERGE_TYPE_CTEMASK:
         break;
       default:
@@ -208,4 +209,5 @@
             // call the init functions
             switch (type) {
+              case PPMERGE_TYPE_CTEMASK:
               case PPMERGE_TYPE_BIAS:
               case PPMERGE_TYPE_FLAT:
@@ -252,4 +254,5 @@
                 // Start a job
                 switch (type) {
+                  case PPMERGE_TYPE_CTEMASK:
                   case PPMERGE_TYPE_BIAS:
                   case PPMERGE_TYPE_FLAT:
@@ -408,4 +411,28 @@
             }
 
+	    // calculate CTEMASK after stats so stats reflect median image
+            if (type == PPMERGE_TYPE_CTEMASK && outRO) {
+		// need to apply range cuts on the output image
+		psAssert (outRO->mask, "mask is not defined");
+		psAssert (outRO->mask->numCols == outRO->image->numCols, "mismatch between image and mask");
+		psAssert (outRO->mask->numRows == outRO->image->numRows, "mismatch between image and mask");
+
+		// CTEMASK parameters
+		float cteMin = psMetadataLookupF32(NULL, arguments, "CTE.MIN"); // Number of fringe points
+
+		char *cteMaskName = psMetadataLookupStr (&mdok, config->arguments, "MASK.SET.VALUE");
+		psImageMaskType cteMaskValue = pmConfigMaskGet(cteMaskName, config);
+
+		psF32 **outputImage = outRO->image->data.F32; 
+		psImageMaskType **outputMask = outRO->mask->data.PS_TYPE_IMAGE_MASK_DATA; 
+		for (int iy = 0; iy < outRO->image->numRows; iy++) {
+		    for (int ix = 0; ix < outRO->image->numCols; ix++) {
+			if (outputImage[iy][ix] < cteMin) {
+			    outputMask[iy][ix] |= cteMaskValue;
+			}
+		    }
+		}
+            }
+
             psFree(outRO);
             cellNum++;
Index: /trunk/ppMerge/src/ppMergeScaleZero.c
===================================================================
--- /trunk/ppMerge/src/ppMergeScaleZero.c	(revision 23462)
+++ /trunk/ppMerge/src/ppMergeScaleZero.c	(revision 23463)
@@ -35,4 +35,5 @@
       case PPMERGE_TYPE_BIAS:
       case PPMERGE_TYPE_DARK:
+      case PPMERGE_TYPE_CTEMASK:
         // Nothing to measure
         return true;
