Index: trunk/psModules/src/concepts/pmConceptsUpdate.c
===================================================================
--- trunk/psModules/src/concepts/pmConceptsUpdate.c	(revision 13034)
+++ trunk/psModules/src/concepts/pmConceptsUpdate.c	(revision 20095)
@@ -25,64 +25,75 @@
         // Check for cell concepts updates
 
-	bool xStatus, yStatus; // Status of MD lookups
-	psImageBinning *binning = psImageBinningAlloc();
-	binning->nXbin = psMetadataLookupS32(&xStatus, cell->concepts, "CELL.XBIN");
-	binning->nYbin = psMetadataLookupS32(&yStatus, cell->concepts, "CELL.YBIN");
-	if (!xStatus || !yStatus) {
-	    // XXX should this be an error condition?
-	    psFree (binning);
-	    return true;
-	}
-	if (!binning->nXbin || !binning->nXbin) {
-	    // XXX should this be an error condition?
-	    psFree (binning);
-	    return true;
-	}
+        // CELL.READNOISE needs to be updated if specified in ADU
+        if (psMetadataLookup(cell->concepts, "CELL.READNOISE.UPDATE")) {
+            float gain = psMetadataLookupF32(NULL, cell->concepts, "CELL.GAIN"); // Gain for cell
+            if (isfinite(gain)) {
+                psMetadataItem *rn = psMetadataLookup(cell->concepts, "CELL.READNOISE"); // Read noise
+                psAssert(rn && rn->type == PS_TYPE_F32, "Should be of the correct type");
+                rn->data.F32 *= gain;
+                psMetadataRemoveKey(cell->concepts, "CELL.READNOISE.UPDATE");
+            }
+        }
+
+        bool xStatus, yStatus; // Status of MD lookups
+        psImageBinning *binning = psImageBinningAlloc();
+        binning->nXbin = psMetadataLookupS32(&xStatus, cell->concepts, "CELL.XBIN");
+        binning->nYbin = psMetadataLookupS32(&yStatus, cell->concepts, "CELL.YBIN");
+        if (!xStatus || !yStatus) {
+            // XXX should this be an error condition?
+            psFree (binning);
+            return true;
+        }
+        if (!binning->nXbin || !binning->nXbin) {
+            // XXX should this be an error condition?
+            psFree (binning);
+            return true;
+        }
 
         // CELL.TRIMSEC needs to be updated for the binning
         if (psMetadataLookup(cell->concepts, "CELL.TRIMSEC.UPDATE")) {
-	    psRegion *trimsec = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC"); // Trim section
-	    *trimsec = psImageBinningSetRuffRegion (binning, *trimsec);
-	    // force integer pixels : truncate x0, roundup x1:
-	    trimsec->x0 = (int)trimsec->x0;
-	    if (trimsec->x1 > (int)trimsec->x1) {
-		trimsec->x1 = (int)trimsec->x1 + 1;
-	    } else {
-		trimsec->x1 = (int)trimsec->x1;
-	    }		
-	    trimsec->y0 = (int)trimsec->y0;
-	    if (trimsec->y1 > (int)trimsec->y1) {
-		trimsec->y1 = (int)trimsec->y1 + 1;
-	    } else {
-		trimsec->y1 = (int)trimsec->y1;
-	    }		
-	    psMetadataRemoveKey(cell->concepts, "CELL.TRIMSEC.UPDATE");
+            psRegion *trimsec = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC"); // Trim section
+            *trimsec = psImageBinningSetRuffRegion (binning, *trimsec);
+            // force integer pixels : truncate x0, roundup x1:
+            trimsec->x0 = (int)trimsec->x0;
+            if (trimsec->x1 > (int)trimsec->x1) {
+                trimsec->x1 = (int)trimsec->x1 + 1;
+            } else {
+                trimsec->x1 = (int)trimsec->x1;
+            }
+            trimsec->y0 = (int)trimsec->y0;
+            if (trimsec->y1 > (int)trimsec->y1) {
+                trimsec->y1 = (int)trimsec->y1 + 1;
+            } else {
+                trimsec->y1 = (int)trimsec->y1;
+            }
+            psMetadataRemoveKey(cell->concepts, "CELL.TRIMSEC.UPDATE");
         }
 
         // CELL.BIASSEC needs to be updated for the binning
         if (psMetadataLookup(cell->concepts, "CELL.BIASSEC.UPDATE")) {
-	    psList *biassecs = psMetadataLookupPtr(NULL, cell->concepts, "CELL.BIASSEC"); // Bias sections
-	    psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, true); // Iterator
-	    psRegion *biassec; // Bias region, from iteration
-	    while ((biassec = psListGetAndIncrement(biassecsIter))) {
-		*biassec = psImageBinningSetRuffRegion (binning, *biassec);
-		// force integer pixels : truncate x0, roundup x1:
-		biassec->x0 = (int)biassec->x0;
-		if (biassec->x1 > (int)biassec->x1) {
-		    biassec->x1 = (int)biassec->x1 + 1;
-		} else {
-		    biassec->x1 = (int)biassec->x1;
-		}		
-		biassec->y0 = (int)biassec->y0;
-		if (biassec->y1 > (int)biassec->y1) {
-		    biassec->y1 = (int)biassec->y1 + 1;
-		} else {
-		    biassec->y1 = (int)biassec->y1;
-		}		
-	    }
-	    psFree(biassecsIter);
-	    psMetadataRemoveKey(cell->concepts, "CELL.BIASSEC.UPDATE");
+            psList *biassecs = psMetadataLookupPtr(NULL, cell->concepts, "CELL.BIASSEC"); // Bias sections
+            psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, true); // Iterator
+            psRegion *biassec; // Bias region, from iteration
+            while ((biassec = psListGetAndIncrement(biassecsIter))) {
+                *biassec = psImageBinningSetRuffRegion (binning, *biassec);
+                // force integer pixels : truncate x0, roundup x1:
+                biassec->x0 = (int)biassec->x0;
+                if (biassec->x1 > (int)biassec->x1) {
+                    biassec->x1 = (int)biassec->x1 + 1;
+                } else {
+                    biassec->x1 = (int)biassec->x1;
+                }
+                biassec->y0 = (int)biassec->y0;
+                if (biassec->y1 > (int)biassec->y1) {
+                    biassec->y1 = (int)biassec->y1 + 1;
+                } else {
+                    biassec->y1 = (int)biassec->y1;
+                }
+            }
+            psFree(biassecsIter);
+            psMetadataRemoveKey(cell->concepts, "CELL.BIASSEC.UPDATE");
         }
-	psFree (binning);
+        psFree (binning);
     }
 
