Index: trunk/ppImage/src/ppImageDetrendNonLinear.c
===================================================================
--- trunk/ppImage/src/ppImageDetrendNonLinear.c	(revision 5858)
+++ trunk/ppImage/src/ppImageDetrendNonLinear.c	(revision 5976)
@@ -6,7 +6,7 @@
     psVector *coeff = dataItem->data.V; // The coefficient vector
     if (coeff->type.type != PS_TYPE_F64) {
-	psVector *temp = psVectorCopy(NULL, coeff, PS_TYPE_F64); // F64 version
-	psFree (coeff);
-	coeff = temp;
+        psVector *temp = psVectorCopy(NULL, coeff, PS_TYPE_F64); // F64 version
+        psFree (coeff);
+        coeff = temp;
     }
     psPolynomial1D *correction = psPolynomial1DAlloc(coeff->n - 1, PS_POLYNOMIAL_ORD);
@@ -17,5 +17,5 @@
     psFree(correction);
     return true;
-}    
+}
 
 bool ppDetrendNonLinearLookup (pmReadout *input, psMetadataItem *dataItem) {
@@ -25,8 +25,8 @@
     psLookupTable *table = psLookupTableAlloc(name, "%f %f", 0);
     if (psLookupTableRead(table) <= 0) {
-	psErrorStackPrint(stderr, "Unable to read non-linearity correction file "
-			  "%s --- ignored\n", name);
-	return false;
-    } 
+        psErrorStackPrint(stderr, "Unable to read non-linearity correction file "
+                          "%s --- ignored\n", name);
+        return false;
+    }
 #ifdef PRODUCTION
     pmNonLinearityLookup(input, table);
@@ -38,5 +38,5 @@
     psFree(table);
     return true;
-}    
+}
 
 bool ppDetrendNonLinear (pmCell *cell, pmReadout *input, ppOptions *options) {
@@ -46,51 +46,62 @@
     switch (options->nonLinearType) {
       case PS_DATA_VECTOR:
-	ppDetrendNonLinearPolynomial (input, options->nonLinearData);
-	return true;
+        ppDetrendNonLinearPolynomial (input, options->nonLinearData);
+        return true;
 
       case PS_DATA_STRING:
-	ppDetrendNonLinearLookup (input, options->nonLinearData);
-	return true;
+        ppDetrendNonLinearLookup (input, options->nonLinearData);
+        return true;
 
       case PS_DATA_METADATA:
-	// XXX this is somewhat confusing : let's wrap in a function when i understand it
-	concept = pmCellGetConcept(cell, options->nonLinearSource);
-	if (! concept) {
-	    psLogMsg("phase2", PS_LOG_WARN, "Unable to find value of concept %s "
-		     "for non-linearity correction --- ignored.\n", options->nonLinearSource);
-	    return false;
-	} 
-	if (concept->type != PS_DATA_STRING) {
-	    psLogMsg("phase2", PS_LOG_WARN, "Type for concept %s isn't STRING, as"
-		     " expected for non-linearity correction --- ignored.\n",
-		     concept);
-	    return false;
-	} 
+        // XXX EAM: this is somewhat confusing : let's wrap in a function when i understand it
 
-	// Get the value of the concept
-	psString conceptValue = concept->data.V;
-	psMetadata *folder = (psMetadata *)options->nonLinearData->data.V;
-	psMetadataItem *optionItem = psMetadataLookup(folder, conceptValue);
-	if (!optionItem) {
-	    psLogMsg("phase2", PS_LOG_WARN, "Unable to find %s in NONLIN.DATA"
-		     " --- ignored.\n", conceptValue);
-	    return false;
-	} 
+        // Go looking for the value in the hierarchy
+        concept = psMetadataLookup(cell->concepts, options->nonLinearSource);
+        if (! concept) {
+            pmChip *chip = cell->parent;// Parent chip
+            concept = psMetadataLookup(chip->concepts, options->nonLinearSource);
+            if (! concept) {
+                pmFPA *fpa = chip->parent; // Parent FPA
+                concept = psMetadataLookup(fpa->concepts, options->nonLinearSource);
+                if (! concept) {
+                    psLogMsg("phase2", PS_LOG_WARN, "Unable to find value of concept %s "
+                             "for non-linearity correction --- ignored.\n", options->nonLinearSource);
+                    return false;
+                }
+            }
+        }
 
-	switch (optionItem->type) {
-	  case PS_DATA_VECTOR:
-	    ppDetrendNonLinearPolynomial (input, optionItem);
-	    return true;
-	  case PS_DATA_STRING:
-	    ppDetrendNonLinearLookup (input, optionItem);
-	    return true;
-	  default:
-	    psLogMsg("phase2", PS_LOG_WARN, "Non-linearity correction "
-		     "desired but unable to interpret NONLIN.DATA for %s"
-		     " --- ignored\n", conceptValue);
-	    return false;
-	}
+        if (concept->type != PS_DATA_STRING) {
+            psLogMsg("phase2", PS_LOG_WARN, "Type for concept %s isn't STRING, as"
+                     " expected for non-linearity correction --- ignored.\n",
+                     concept);
+            return false;
+        }
+
+        // Get the value of the concept
+        psString conceptValue = concept->data.V;
+        psMetadata *folder = (psMetadata *)options->nonLinearData->data.V;
+        psMetadataItem *optionItem = psMetadataLookup(folder, conceptValue);
+        if (!optionItem) {
+            psLogMsg("phase2", PS_LOG_WARN, "Unable to find %s in NONLIN.DATA"
+                     " --- ignored.\n", conceptValue);
+            return false;
+        }
+
+        switch (optionItem->type) {
+          case PS_DATA_VECTOR:
+            ppDetrendNonLinearPolynomial (input, optionItem);
+            return true;
+          case PS_DATA_STRING:
+            ppDetrendNonLinearLookup (input, optionItem);
+            return true;
+          default:
+            psLogMsg("phase2", PS_LOG_WARN, "Non-linearity correction "
+                     "desired but unable to interpret NONLIN.DATA for %s"
+                     " --- ignored\n", conceptValue);
+            return false;
+        }
       default:
-	psAbort("phase2", "Invalid options->nonLinearType");
+        psAbort("phase2", "Invalid options->nonLinearType");
     }
     return true;
