Index: trunk/psModules/src/detrend/Makefile.am
===================================================================
--- trunk/psModules/src/detrend/Makefile.am	(revision 20599)
+++ trunk/psModules/src/detrend/Makefile.am	(revision 20617)
@@ -15,5 +15,6 @@
 	pmDetrendThreads.c \
 	pmShifts.c \
-	pmDark.c
+	pmDark.c \
+	pmRemnance.c
 
 #	pmSkySubtract.c
@@ -31,5 +32,6 @@
 	pmDetrendThreads.h \
 	pmShifts.h \
-	pmDark.h
+	pmDark.h \
+	pmRemnance.h
 
 #	pmSkySubtract.h
Index: trunk/psModules/src/detrend/pmRemnance.c
===================================================================
--- trunk/psModules/src/detrend/pmRemnance.c	(revision 20617)
+++ trunk/psModules/src/detrend/pmRemnance.c	(revision 20617)
@@ -0,0 +1,60 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+
+#include "pmFPA.h"
+#include "pmRemnance.h"
+
+#define THRESHOLD 4.0                   // Threshold above background
+
+
+bool pmRemance(pmReadout *ro,           ///< Readout with input image
+               psMaskType maskVal,      ///< Value of mask
+               psMaskType maskRem       ///< Value to give remance
+               )
+{
+    PM_ASSERT_READOUT_NON_NULL(ro, false);
+    PM_ASSERT_READOUT_IMAGE(ro, false);
+    PM_ASSERT_READOUT_MASK(ro, false);
+
+    psImage *image = ro->image, *mask = ro->mask; // Mask and image from readout
+    int numCols = image->numCols, numRows = image->numRows; // Size of image
+
+    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator
+
+    psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics
+    if (!psImageBackground(stats, NULL, image, mask, maskVal, rng)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to calculate image statistics.");
+        psFree(stats);
+        psFree(rng);
+        return false;
+    }
+    psFree(rng);
+    float thresh = stats->robustMedian + THRESHOLD * stats->robustStdev; // Threshold for significant pixels
+    psFree(stats);
+
+    // Starting at the bottom of the detector, mask pixels that are significant
+    int numMasked = 0;                  // Number of pixels masked
+    for (int x = 0; x < numCols; x++) {
+        bool significant = true;        // Are pixels significant?
+        for (int y = 0; significant && y < numRows; y++) {
+            if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) {
+                continue;
+            }
+            if (image->data.F32[y][x] > thresh) {
+                mask->data.PS_TYPE_MASK_DATA[y][x] |= maskRem;
+                numMasked++;
+            } else {
+                significant = false;
+            }
+        }
+    }
+
+    psMetadataAddS32(ro->analysis, PS_LIST_TAIL, PM_REMNANCE_ANALYSIS_NUM, 0,
+                     "Number of remnance pixels masked", numMasked);
+
+    return true;
+}
Index: trunk/psModules/src/detrend/pmRemnance.h
===================================================================
--- trunk/psModules/src/detrend/pmRemnance.h	(revision 20617)
+++ trunk/psModules/src/detrend/pmRemnance.h	(revision 20617)
@@ -0,0 +1,20 @@
+#ifndef PM_REMNANCE_H
+#define PM_REMNANCE_H
+
+#include <pslib.h>
+#include "pmFPA.h"
+
+// Analysis metadata names
+#define PM_REMNANCE_ANALYSIS_NUM "DETREND.REMNANCE.NUM" // Number of masked remnance pixels
+
+// Mask remnance pixels
+//
+// By "remnance", we mean pixels left over from previous exposures.
+// GPC1 leaves remnance that flows down from where the annoyed pixels are.
+bool pmRemance(pmReadout *ro,           ///< Readout with input image
+               psMaskType maskVal,      ///< Value of mask
+               psMaskType maskRem       ///< Value to give remance
+    );
+
+
+#endif
