Index: /branches/eam_branches/ipp-dev-20210817/ppImage/src/ppImageDetrendPattern.c
===================================================================
--- /branches/eam_branches/ipp-dev-20210817/ppImage/src/ppImageDetrendPattern.c	(revision 41804)
+++ /branches/eam_branches/ipp-dev-20210817/ppImage/src/ppImageDetrendPattern.c	(revision 41805)
@@ -52,4 +52,5 @@
 
 	pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.INPUT");
+
 	pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
 	*view = *inputView;
@@ -79,32 +80,41 @@
                 ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
             }
-            //psWarning ("Row: %d\n", doPattern);
             if (!doPattern) continue;
 
-	    // A very detailed log message. 
-            const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
-            const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
-            psLogMsg("ppImage", PS_LOG_INFO, "Performing row pattern correction for %s, %s\n", chipName, cellName);
-
-            // process each of the readouts
-            pmReadout *readout;         // Readout from cell
-            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
-                if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-                    ESCAPE(false, "load failure for Readout");
-                }
-                if (!readout->data_exists) {
-                    continue;
-                }
-
-                // Perform pattern correction
-                if (!pmPatternRow(readout, options->patternRowOrder, options->patternRowIter,
-                                  options->patternRowRej, options->patternRowThresh, options->patternRowMean,
-                                  options->patternRowStdev, options->maskValue, options->darkMask)) {
-                    psFree(view);
-                    return(false);
-                }
-            }
-
-	}
+	    // switch to test threaded version
+	    if (true) {
+		// I need to allocate a view here to be freed by the
+		// called function below.  
+		pmFPAview *myView = pmFPAviewAlloc(0); // View for local processing
+		*myView = *view;
+
+		// allocate a job, construct the arguments for this job
+		psThreadJob *job = psThreadJobAlloc("PPIMAGE_PATTERN_ROW_CELL");
+		psArrayAdd(job->args, 1, config);
+		psArrayAdd(job->args, 1, input->fpa);
+		psArrayAdd(job->args, 1, chip);
+		psArrayAdd(job->args, 1, cell);
+		psArrayAdd(job->args, 1, myView);
+		psArrayAdd(job->args, 1, options);
+		if (!psThreadJobAddPending(job)) {
+		    return false;
+		}
+	    } else {
+		// bump the counter since it must be freed by the function below.  
+		psMemIncrRefCounter (view); // View for local processing
+		if (!ppImageDetrendPatternApplyCell (config, input->fpa, chip, cell, view, options)) {
+		    return false;
+		}
+	    }
+
+	}
+
+        // wait here for the threaded jobs to finish
+	// if no threads are allocated, this 
+        if (!psThreadPoolWait(true, true)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction.");
+            return false;
+        }
+
 	psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_ROW",PS_META_REPLACE,"PATTERN.ROW correction applied",true);
 	psFree(view);
@@ -266,2 +276,30 @@
     return false;
 }
+
+bool ppImageDetrendPatternApplyCell (pmConfig *config, pmFPA *fpa, pmChip *chip, pmCell *cell, const pmFPAview *view, const ppImageOptions *options) {
+  
+    // A very detailed log message. 
+    const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
+    const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
+    psLogMsg("ppImage", PS_LOG_INFO, "Performing row pattern correction for %s, %s\n", chipName, cellName);
+
+    // process each of the readouts
+    pmReadout *readout;         // Readout from cell
+    while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
+	if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+	    ESCAPE(false, "load failure for Readout");
+	}
+	if (!readout->data_exists) {
+	    continue;
+	}
+
+	// Perform pattern correction
+	if (!pmPatternRow(readout, options->patternRowOrder, options->patternRowIter,
+			  options->patternRowRej, options->patternRowThresh, options->patternRowMean,
+			  options->patternRowStdev, options->maskValue, options->darkMask)) {
+	    psFree (view);
+	    return(false);
+	}
+    }
+    psFree (view); // supplied view must be freeable
+}
Index: /branches/eam_branches/ipp-dev-20210817/ppImage/src/ppImageSetThreads.c
===================================================================
--- /branches/eam_branches/ipp-dev-20210817/ppImage/src/ppImageSetThreads.c	(revision 41804)
+++ /branches/eam_branches/ipp-dev-20210817/ppImage/src/ppImageSetThreads.c	(revision 41805)
@@ -4,4 +4,6 @@
 
 #include "ppImage.h"
+
+/** NOTE 2021.09.03 : these functions are not currently being used **/
 
 bool ppImageThread_ppImageDetrendReadout (psThreadJob *job) {
@@ -15,12 +17,28 @@
 }
 
+bool ppImageThread_ppImageDetrendPatternApplyCell (psThreadJob *job) {
+
+    pmConfig *config        = job->args->data[0];
+    ppImageOptions *options = job->args->data[1];
+    pmFPAview *view         = job->args->data[2];
+
+    bool status = ppImageDetrendPatternApplyCell (config, fpa, chip, cell, view, options);
+    return status;
+}
+
 bool ppImageSetThreads () {
 
-    psThreadTask *task = NULL;
-
-    task = psThreadTaskAlloc ("PPIMAGE_DETREND_READOUT", 3);
+  if (0) {
+    psThreadTask *task = psThreadTaskAlloc ("PPIMAGE_DETREND_READOUT", 3);
     task->function = &ppImageThread_ppImageDetrendReadout;
     psThreadTaskAdd (task);
+  }
 
+    {
+    psThreadTask *task = psThreadTaskAlloc("PPIMAGE_PATTERN_ROW_CELL", 7);
+    task->function = &ppImageThread_ppImageDetrendPatternApplyCell;
+    psThreadTaskAdd(task);
+    psFree(task);
+    }
     return true;
 }
