Index: trunk/psModules/src/concepts/pmConceptsStandard.c
===================================================================
--- trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 19980)
+++ trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 20095)
@@ -46,4 +46,87 @@
     return NAN;
 }
+
+
+psMetadataItem *p_pmConceptParse_CELL_READNOISE(const psMetadataItem *concept,
+                                                const psMetadataItem *pattern,
+                                                pmConceptSource source,
+                                                const psMetadata *cameraFormat,
+                                                const pmFPA *fpa,
+                                                const pmChip *chip,
+                                                const pmCell *cell)
+{
+    assert(concept);
+    assert(pattern);
+    assert(cameraFormat);
+    assert(cell);
+
+    float rn = psMetadataItemParseF32(concept); // Read noise
+    if (isfinite(rn)) {
+        bool mdok;                      // Status of MD lookup
+        psMetadata *formats = psMetadataLookupMetadata(&mdok, cameraFormat, "FORMATS");
+        if (mdok && formats) {
+            psString format = psMetadataLookupStr(&mdok, formats, pattern->name);
+            if (mdok && strlen(format) > 0) {
+                if (strcasecmp(format, "ADU") == 0) {
+                    float gain = psMetadataLookupF32(NULL, cell->concepts, "CELL.GAIN"); // Gain (e/ADU)
+                    if (!isfinite(gain)) {
+                        // Will need to update the readnoise once the gain is available
+                        psMetadataAddBool(cell->concepts, PS_LIST_TAIL, "CELL.READNOISE.UPDATE",
+                                          PS_META_REPLACE,
+                                          "Need to update CELL.READNOISE when the gain is available.", true);
+                    } else {
+                        rn *= gain;
+                    }
+                } else {
+                    psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unrecognised format for CELL.READNOISE: %s",
+                            format);
+                    return NULL;
+                }
+            }
+        }
+    }
+
+    return psMetadataItemAllocF32(pattern->name, pattern->comment, rn);
+}
+
+psMetadataItem *p_pmConceptFormat_CELL_READNOISE(const psMetadataItem *concept,
+                                                 pmConceptSource source,
+                                                 const psMetadata *cameraFormat,
+                                                 const pmFPA *fpa,
+                                                 const pmChip *chip,
+                                                 const pmCell *cell)
+{
+    assert(concept);
+    assert(cell);
+    assert(concept->type == PS_TYPE_F32);
+
+    float rn = concept->data.F32;       // Read noise
+    if (isfinite(rn)) {
+        bool mdok;                      // Status of MD lookup
+        psMetadata *formats = psMetadataLookupMetadata(&mdok, cameraFormat, "FORMATS");
+        if (mdok && formats) {
+            psString format = psMetadataLookupStr(&mdok, formats, concept->name);
+            if (mdok && strlen(format) > 0) {
+                if (strcasecmp(format, "ADU") == 0) {
+                    if (!psMetadataLookup(cell->concepts, "CELL.READNOISE.UPDATE")) {
+                        // Gain correction has been applied, so we need to reverse it to format
+                        float gain = psMetadataLookupF32(NULL, cell->concepts, "CELL.GAIN"); // Gain (e/ADU)
+                        if (!isfinite(gain)) {
+                            psWarning("CELL.READNOISE is supposed to be in ADU, but CELL.GAIN isn't set");
+                        }
+                        rn /= gain;
+                    }
+                } else {
+                    psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unrecognised format for CELL.READNOISE: %s",
+                            format);
+                    return NULL;
+                }
+            }
+        }
+    }
+
+    return psMetadataItemAllocF32(concept->name, concept->comment, rn);
+}
+
 
 // TELTEMPS : parse a list of the form 'X1 X2 X3 X4 X5 ...' : for now use median
