Index: trunk/ppImage/src/ppImage.h
===================================================================
--- trunk/ppImage/src/ppImage.h	(revision 29549)
+++ trunk/ppImage/src/ppImage.h	(revision 29833)
@@ -155,5 +155,6 @@
 bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options);
 
-bool ppImageDetrendNonLinear(pmReadout *input, ppImageOptions *options);
+//bool ppImageDetrendNonLinear(pmReadout *input, ppImageOptions *options);
+bool ppImageDetrendNonLinear(pmReadout *input, pmFPAview *linearity, pmConfig *config);
 bool ppImageDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem);
 bool ppImageDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem);
Index: trunk/ppImage/src/ppImageArguments.c
===================================================================
--- trunk/ppImage/src/ppImageArguments.c	(revision 29549)
+++ trunk/ppImage/src/ppImageArguments.c	(revision 29833)
@@ -24,4 +24,5 @@
     fprintf(stderr, "\t-mask/-masklist: Mask image.\n");
     fprintf(stderr, "\t-fringe/-fringelist: Fringe image and data.\n");
+    fprintf(stderr, "\t-linearity/-linearlist: linearity correction file.\n");
     fprintf(stderr, "\n");
     exit (2);
@@ -120,4 +121,5 @@
     pmConfigFileSetsMD (config->arguments, &argc, argv, "MASK", "-mask", "-masklist");
     pmConfigFileSetsMD (config->arguments, &argc, argv, "FRINGE", "-fringe", "-fringelist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "LINEARITY", "-linearity", "-linearlist");
 
     // chip selection is used to limit chips to be processed
Index: trunk/ppImage/src/ppImageDefineFile.c
===================================================================
--- trunk/ppImage/src/ppImageDefineFile.c	(revision 29549)
+++ trunk/ppImage/src/ppImageDefineFile.c	(revision 29833)
@@ -15,5 +15,5 @@
         file = pmFPAfileDefineFromArgs(&status, config, filerule, argname);
         if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition ARG LIST");
             return false;
         }
@@ -23,5 +23,5 @@
         file = pmFPAfileDefineFromRun(&status, NULL, config, filerule);
         if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition RUN");
             return false;
         }
@@ -31,5 +31,5 @@
         file = pmFPAfileDefineFromConf(&status, config, filerule);
         if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition CONFIG");
             return false;
         }
@@ -39,5 +39,5 @@
         file = pmFPAfileDefineFromDetDB(&status, config, filerule, input, detrendType);
         if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition DETREND");
             return false;
         }
Index: trunk/ppImage/src/ppImageDetrendFree.c
===================================================================
--- trunk/ppImage/src/ppImageDetrendFree.c	(revision 29549)
+++ trunk/ppImage/src/ppImageDetrendFree.c	(revision 29833)
@@ -13,4 +13,5 @@
     "PPIMAGE.FLAT",
     "PPIMAGE.SHUTTER",
+    "PPIMAGE.LINEARITY",
     NULL
 };
@@ -23,4 +24,5 @@
 
 	pmFPAfile *file = psMetadataLookupPtr(&status, config->files, detrendTypes[i]); // File of interest
+	psTrace("pmFPAfileFree",1,"Working on %s\n",detrendTypes[i]);
 	if (!file) continue; // not all detrends are used in any given run
 
Index: trunk/ppImage/src/ppImageDetrendNonLinear.c
===================================================================
--- trunk/ppImage/src/ppImageDetrendNonLinear.c	(revision 29549)
+++ trunk/ppImage/src/ppImageDetrendNonLinear.c	(revision 29833)
@@ -44,5 +44,42 @@
 }
 
-bool ppImageDetrendNonLinear(pmReadout *input, ppImageOptions *options) {
+
+bool ppImageDetrendNonLinear(pmReadout *input, pmFPAview *detview, pmConfig  *config) {
+    bool status;
+
+    pmFPAfile *linearity_file = psMetadataLookupPtr(&status,config->files,"PPIMAGE.LINEARITY");
+    psFits *linearity_fits = linearity_file->fits;
+
+    char *extname = psMetadataLookupStr(&status,input->parent->concepts,"CELL.NAME");
+    if (!extname) {
+	psError(PS_ERR_IO, false, "missing CELL.NAME in concepts");
+	return(false);
+    }
+
+    if (!psFitsMoveExtName(linearity_fits,extname)) {
+	psError(PS_ERR_IO, false, "Unable to move to non-linearity table %s", extname);
+	return(false);
+    }
+  
+    psArray *table = psFitsReadTable(linearity_fits);
+    if (!table) {
+	psError(PS_ERR_IO, false, "Unable to read non-linearity table.\n");
+	return(false);
+    }
+
+    // It might be better to pack lookup table here...
+    // Why? I only use that lookup table once for the single cell it matches. 
+  
+    if (!pmNonLinearityApply(input,table)) {
+	psError(PS_ERR_UNKNOWN, false, "Unable to apply non-linearity corrections.\n");
+	psFree (table);
+	return(false);
+    }	    
+    psFree (table);
+
+    return true;
+}
+
+bool ppImageDetrendNonLinear_Original(pmReadout *input, ppImageOptions *options) {
 
     psMetadataItem *concept;
@@ -59,6 +96,4 @@
 
       case PS_DATA_METADATA:
-        // XXX EAM: this is somewhat confusing : let's wrap in a function when i understand it
-
         // Go looking for the value in the hierarchy
         concept = psMetadataLookup(cell->concepts, options->nonLinearSource);
Index: trunk/ppImage/src/ppImageDetrendReadout.c
===================================================================
--- trunk/ppImage/src/ppImageDetrendReadout.c	(revision 29549)
+++ trunk/ppImage/src/ppImageDetrendReadout.c	(revision 29833)
@@ -51,11 +51,23 @@
     }
 
-
-# if 0
+    // Subtract the overscan
+    if (options->doOverscan) {
+      if (!pmOverscanSubtract (input, options->overscan)) {
+	psError(PS_ERR_UNKNOWN, false, "Unable to subtract overscan.");
+	psFree(detview);
+	return false;
+      }
+    }
+
     // Non-linearity correction
     if (options->doNonLin) {
-        ppImageDetrendNonLinear(detrend->input, input, options);
-    }
-# endif
+      //      linearity = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.LINEARITY");
+      if (!ppImageDetrendNonLinear(input,detview,config)) {
+	psError(PS_ERR_UNKNOWN, false, "Unable to correct NonLinearity");
+	psFree(detview);
+	return(false);
+      }
+      /*       ppImageDetrendNonLinear(detrend->input, input, options); */
+    }
 
     // set up the dark and bias
@@ -77,7 +89,7 @@
     }
 
-    // Bias, dark and overscan subtraction are all merged.
-    if (options->doBias || options->doOverscan) {
-        if (!pmBiasSubtract(input, options->overscan, bias, oldDark, view)) {
+    // Bias and temperature-independent-dark subtraction are merged.
+    if (options->doBias) {
+        if (!pmBiasSubtract(input, bias, oldDark, view)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to subtract bias.");
             psFree(detview);
@@ -85,5 +97,5 @@
         }
     }
-
+    
     // Weight on the basis of pixel value needs to be done after the overscan has been subtracted
     if (options->doVarianceBuild) {
Index: trunk/ppImage/src/ppImageLoop.c
===================================================================
--- trunk/ppImage/src/ppImageLoop.c	(revision 29549)
+++ trunk/ppImage/src/ppImageLoop.c	(revision 29833)
@@ -152,5 +152,5 @@
             ESCAPE("Unable to free detrend images");
         }
-
+    
         // Apply the fringe correction
         if (options->doFringe) {
Index: trunk/ppImage/src/ppImageOptions.c
===================================================================
--- trunk/ppImage/src/ppImageOptions.c	(revision 29549)
+++ trunk/ppImage/src/ppImageOptions.c	(revision 29833)
@@ -8,6 +8,6 @@
 {
     psFree(options->overscan);
-    psFree(options->nonLinearData);
-    psFree(options->nonLinearSource);
+    // psFree(options->nonLinearData);
+    // psFree(options->nonLinearSource);
 }
 
@@ -130,6 +130,5 @@
         psMetadataItem *dataItem = psMetadataLookup(recipe, "NONLIN.DATA");
         if (! dataItem) {
-            psLogMsg(__func__, PS_LOG_ERROR, "Non-linearity correction desired, but unable to "
-                     "find NONLIN.DATA in recipe %s.", RECIPE_NAME);
+            psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.DATA in recipe %s.", RECIPE_NAME);
             exit(EXIT_FAILURE);
         }
@@ -147,17 +146,12 @@
             // This is a menu; we need the key
           case PS_DATA_METADATA:
-            {
-                bool status;
-                options->nonLinearSource = psMetadataLookupStr(&status, recipe, "NONLIN.SOURCE");
-                if (! status || ! options->nonLinearSource) {
-                    psLogMsg(__func__, PS_LOG_ERROR, "Non-linearity correction desired, but unable to "
-                            "find NONLIN.SOURCE in recipe %s.", RECIPE_NAME);
-                    exit(EXIT_FAILURE);
-                }
-            }
+	    options->nonLinearSource = psMetadataLookupStr(&status, recipe, "NONLIN.SOURCE");
+	    if (! status || ! options->nonLinearSource) {
+		psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.SOURCE in recipe %s.", RECIPE_NAME);
+		exit(EXIT_FAILURE);
+	    }
             break;
           default:
-            psLogMsg(__func__, PS_LOG_ERROR, "Non-linearity correction desired, but "
-                    "NONLIN.DATA is of invalid type in recipe %s.", RECIPE_NAME);
+            psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but NONLIN.DATA is of invalid type in recipe %s.", RECIPE_NAME);
             exit(EXIT_FAILURE);
         }
Index: trunk/ppImage/src/ppImageParseCamera.c
===================================================================
--- trunk/ppImage/src/ppImageParseCamera.c	(revision 29549)
+++ trunk/ppImage/src/ppImageParseCamera.c	(revision 29833)
@@ -73,4 +73,13 @@
             return NULL;
         }
+    }
+
+    if (options->doNonLin) {
+      if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.LINEARITY", "LINEARITY",
+			     PM_FPA_FILE_LINEARITY, PM_DETREND_TYPE_LINEARITY)) {
+	psError(PS_ERR_IO, false, "Can't find a non-linearity correction source");
+	psFree(options);
+	return NULL;
+      }
     }
 
