Index: trunk/psModules/src/objects/pmSourceIO_CMF.c.in
===================================================================
--- trunk/psModules/src/objects/pmSourceIO_CMF.c.in	(revision 35038)
+++ trunk/psModules/src/objects/pmSourceIO_CMF.c.in	(revision 35610)
@@ -457,6 +457,14 @@
     bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
 
-    psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
-    psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
+    // First look for radial bin definition in readout->analysis ...
+    psVector *radMin = psMetadataLookupPtr (&status, readout->analysis, "RADIAL.ANNULAR.BINS.LOWER");
+    psVector *radMax = psMetadataLookupPtr (&status, readout->analysis, "RADIAL.ANNULAR.BINS.UPPER");
+    if (!radMin) {
+        // .. if not found use the recipe values
+        radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
+        radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
+    }
+    psAssert(radMin != NULL, "unable to find RADIAL.ANNULAR.BINS.LOWER");
+    psAssert(radMax != NULL, "unable to find RADIAL.ANNULAR.BINS.LOWER");
     psAssert (radMin->n == radMax->n, "inconsistent annular bins");
 
@@ -610,5 +618,66 @@
 }
 
-bool pmSourcesRead_CMF_@CMFMODE@_XSRC(psFits *fits, psMetadata *hduHeader, psArray *sources, long *sourceIndex)
+static bool setRadialBinsInAnalysis(pmReadout *readout, psMetadata *tableHeader)
+{
+    if (!readout->analysis) {
+        readout->analysis = psMetadataAlloc();
+    }
+
+    bool status;
+    psVector *oldRMin = psMetadataLookupVector(&status, readout->analysis, "RADIAL.ANNULAR.BINS.LOWER");
+    psVector *oldRMax = psMetadataLookupVector(&status, readout->analysis, "RADIAL.ANNULAR.BINS.UPPER");
+
+    psVector *rMin = psVectorAllocEmpty(20, PS_TYPE_F32);
+    psVector *rMax = psVectorAllocEmpty(20, PS_TYPE_F32);
+
+    for (int i = 0; ; i++) {
+        char key [24];
+        sprintf(key, "RMIN_%02d", i);
+        psF32 rMinVal = psMetadataLookupF32(&status, tableHeader, key);
+        if (!status) {
+            break;
+        }
+        psVectorAppend(rMin, rMinVal);
+
+        sprintf(key, "RMAX_%02d", i);
+        psF32 rMaxVal = psMetadataLookupF32(&status, tableHeader, key);
+        if (!status) {
+            break;
+        }
+        psVectorAppend(rMax, rMaxVal);
+    }
+
+    if (rMin->n != rMax->n) {
+        psError(PS_ERR_UNKNOWN, true, "number of RMIN entries %ld does not equal number of RMAX entries %ld", 
+            rMin->n, rMax->n);
+        return false;
+    }
+
+    if (oldRMin) {
+        if (oldRMin->n != rMin->n) {
+            psError(PS_ERR_UNKNOWN, true, "number of RMIN entries in header: %ld does not equal number of RMAX entries in analysis: %ld", 
+                rMin->n, oldRMin->n);
+            return false;
+        }
+    } else {
+        psMetadataAddVector(readout->analysis, PS_LIST_TAIL, "RADIAL.ANNULAR.BINS.LOWER", PS_META_REPLACE, "", rMin);
+    }
+    psFree(rMin);
+
+    if (oldRMax) {
+        if (oldRMax->n != rMax->n) {
+            psError(PS_ERR_UNKNOWN, true, "number of RMIN entries in header: %ld does not equal number of RMAX entries in analysis: %ld", 
+                rMax->n, oldRMax->n);
+            return false;
+        }
+    } else {
+        psMetadataAddVector(readout->analysis, PS_LIST_TAIL, "RADIAL.ANNULAR.BINS.UPPER", PS_META_REPLACE, "", rMax);
+    }
+    psFree(rMax);
+
+    return true;
+}
+
+bool pmSourcesRead_CMF_@CMFMODE@_XSRC(psFits *fits, pmReadout *readout, psMetadata *hduHeader, psMetadata *tableHeader, psArray *sources, long *sourceIndex)
 {
     PS_ASSERT_PTR_NON_NULL(fits, false);
@@ -626,4 +695,9 @@
     float exptime = psMetadataLookupF32(&status, hduHeader, "EXPTIME");
     float magOffset = zeropt + 2.5*log10(exptime);
+
+    if (!setRadialBinsInAnalysis(readout, tableHeader)) {
+        psError(PS_ERR_UNKNOWN, false, "Failed to save radial bins in analysis");
+        return false;
+    }
 
     for (long i = 0; i < numSources; i++) {
@@ -920,5 +994,5 @@
 }
 
-bool pmSourcesRead_CMF_@CMFMODE@_XFIT(psFits *fits, psMetadata *hduHeader, psArray *sources, long *sourceIndex)
+bool pmSourcesRead_CMF_@CMFMODE@_XFIT(psFits *fits, pmReadout *readout, psMetadata *hduHeader, psMetadata *tableHeader, psArray *sources, long *sourceIndex)
 {
     PS_ASSERT_PTR_NON_NULL(fits, false);
@@ -1043,8 +1117,14 @@
 
     // we use this just to define the output vectors (which must be present for all objects)
-    psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
-    psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
+    // First look for radial bin definition in readout->analysis ...
+    psVector *radMin = psMetadataLookupPtr (&status, readout->analysis, "RADIAL.ANNULAR.BINS.LOWER");
+    psVector *radMax = psMetadataLookupPtr (&status, readout->analysis, "RADIAL.ANNULAR.BINS.UPPER");
+    if (!radMin) {
+        // .. if not found use the recipe values
+        radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
+        radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
+    }
+    psAssert (radMin, "this must have been defined and tested earlier!");
     psAssert (radMax, "this must have been defined and tested earlier!");
-    psAssert (radMax->n, "this must have been defined and tested earlier!");
     psAssert (radMin->n == radMax->n, "inconsistent annular bins");
 
@@ -1167,5 +1247,5 @@
 }
 
-bool pmSourcesRead_CMF_@CMFMODE@_XRAD(psFits *fits, pmReadout *readout, psMetadata *hduHeader, psArray *sources, long *sourceIndex)
+bool pmSourcesRead_CMF_@CMFMODE@_XRAD(psFits *fits, pmReadout *readout, psMetadata *hduHeader, psMetadata *tableHeader, psArray *sources, long *sourceIndex)
 {
     PS_ASSERT_PTR_NON_NULL(fits, false);
@@ -1176,4 +1256,9 @@
     if (numSources == 0) {
         psError(psErrorCodeLast(), false, "XRAD Table contains no entries\n");
+        return false;
+    }
+
+    if (!setRadialBinsInAnalysis(readout, tableHeader)) {
+        psError(PS_ERR_UNKNOWN, false, "Failed to save radial bins in analysis");
         return false;
     }
