Index: trunk/psModules/src/objects/pmSourceIO.c
===================================================================
--- trunk/psModules/src/objects/pmSourceIO.c	(revision 32633)
+++ trunk/psModules/src/objects/pmSourceIO.c	(revision 32971)
@@ -57,4 +57,7 @@
 #define BLANK_HEADERS "BLANK.HEADERS"   // Name of metadata in camera configuration containing header names
                                         // for putting values into a blank PHU
+static bool pmReadoutReadXSRC(pmFPAfile *file, char * exttype, psMetadata *hduHeader, psString xsrcname, psArray *sources, long *sourceIndex);
+static bool pmReadoutReadXFIT(pmFPAfile *file, char * exttype, psMetadata *hduHeader, psString xfitname, psArray *sources, long *sourceIndex);
+static bool pmReadoutReadXRAD(pmFPAfile *file, char * exttype, psMetadata *hduHeader, psString xfitname, psArray *sources, long *sourceIndex);
 
 // lookup the EXTNAME values used for table data and image header segments
@@ -961,5 +964,27 @@
         psString dataname = NULL;
         psString deteffname = NULL;
-        if (!pmSourceIOextnames(&headname, &dataname, &deteffname, NULL, NULL, NULL, file, view)) {
+        psString xsrcname = NULL;
+        psString xfitname = NULL;
+        psString xradname = NULL;
+
+        // determine the output table format. Assume if we need to output extendend source
+        // parameters that they may exist in the input. 
+        // XXX: Perhaps we should use different recipe values.
+        // I.E. EXTENDED_SOURCE_ANALYSIS_READ or something like that
+        psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, "PSPHOT");
+        if (!status) {
+	    psError(PS_ERR_UNKNOWN, true, "missing recipe PSPHOT in config data");
+	    return false;
+        }
+        // if this is not TRUE, the output files only contain the psf measurements.
+        bool XSRC_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_ANALYSIS");
+        bool XFIT_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_FITS");
+        bool XRAD_OUTPUT = psMetadataLookupBool(&status, recipe, "RADIAL_APERTURES");
+
+        if (!pmSourceIOextnames(&headname, &dataname, &deteffname, 
+                XSRC_OUTPUT ? &xsrcname : NULL, 
+                XFIT_OUTPUT ? &xfitname : NULL, 
+                XRAD_OUTPUT ? &xradname : NULL,
+                file, view)) {
             return false;
         }
@@ -1039,4 +1064,45 @@
             }
 
+            long *sourceIndex = NULL;
+            if (XSRC_OUTPUT || XFIT_OUTPUT || XRAD_OUTPUT) {
+                long seq_max = -1;
+                for (long i = sources->n -1; i >= 0; i--) {
+                    pmSource *source = sources->data[i];
+                    if (source->seq > seq_max) {
+                        seq_max = source->seq;
+                    }
+                }
+                sourceIndex = psAlloc((seq_max + 1) * sizeof(long));
+                for (long i = 0; i < seq_max; i++) {
+                    sourceIndex[i] = -1;
+                }
+                for (long i = 0; i < sources->n; i++) {
+                    pmSource *source = sources->data[i];
+                    sourceIndex[source->seq] = i;
+                }
+            }
+            if (XSRC_OUTPUT && xsrcname) {
+                if (!pmReadoutReadXSRC(file, exttype, hdu->header, xsrcname, sources, sourceIndex)) {
+                    // XXX: is this an error?
+                    psErrorClear();
+                }
+                psFree(xsrcname);
+            }
+            if (XFIT_OUTPUT && xfitname) {
+                if (!pmReadoutReadXFIT(file, exttype, hdu->header, xfitname, sources, sourceIndex)) {
+                    // XXX: is this an error?
+                    psErrorClear();
+                }
+                psFree(xfitname);
+            }
+            if (XRAD_OUTPUT && xradname) {
+                if (!pmReadoutReadXRAD(file, exttype, hdu->header, xradname, sources, sourceIndex)) {
+                    // XXX: is this an error?
+                    psErrorClear();
+                }
+                psFree(xradname);
+            }
+            psFree(sourceIndex);
+
             if (!pmReadoutReadDetEff(file->fits, readout, deteffname)) {
 #if 0
@@ -1165,3 +1231,179 @@
 }
 
-
+// XXX: We might be able to macroize this and reuse for the other types
+
+static bool pmReadoutReadXSRC(pmFPAfile *file, char *exttype, psMetadata *hduHeader, psString xsrcname, psArray *sources, long *sourceIndex) 
+{
+    if (!psFitsMoveExtName (file->fits, xsrcname)) {
+        psError(PS_ERR_UNKNOWN, false, "cannot find xsrc extension %s in %s", xsrcname, file->filename);
+        return false;
+    }
+
+    psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header
+    if (!tableHeader) psAbort("cannot read table header");
+
+    char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION");
+    if (!xtension) psAbort("cannot read table type");
+    if (strcmp (xtension, "BINTABLE")) {
+        psWarning ("no binary table in extension %s, skipping\n", xsrcname);
+        return false;
+    }
+
+    // XXX these are case-sensitive since the EXTYPE is case-sensitive
+    bool status = false;
+    if (file->type == PM_FPA_FILE_CMF) {
+#ifdef notyet
+        if (!strcmp (exttype, "SMPDATA")) {
+            status  = pmSourcesRead_SMPDATA_XSRC (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DEV_0")) {
+            status  = pmSourcesRead_PS1_DEV_0_XSRC (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DEV_1")) {
+            status  = pmSourcesRead_PS1_DEV_1_XSRC (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V1")) {
+            status  = pmSourcesRead_CMF_PS1_V1_XSRC (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V2")) {
+            status  = pmSourcesRead_CMF_PS1_V2_XSRC (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V3")) {
+            status  = pmSourcesRead_CMF_PS1_V3_XSRC (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V4")) {
+            status  = pmSourcesRead_CMF_PS1_V4_XSRC (file->fits, hduHeader, sources);
+        }
+#endif // notyet
+        if (!strcmp (exttype, "PS1_SV1")) {
+            status  = pmSourcesRead_CMF_PS1_SV1_XSRC (file->fits, hduHeader, sources, sourceIndex);
+        }
+#ifdef notyet
+        if (!strcmp (exttype, "PS1_DV1")) {
+            status  = pmSourcesRead_CMF_PS1_DV1_XSRC (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DV2")) {
+            status  = pmSourcesRead_CMF_PS1_DV2_XSRC (file->fits, hduHeader, sources);
+        }
+#endif // notyet
+    }
+    psFree(tableHeader);
+    return status;
+}
+
+static bool pmReadoutReadXFIT(pmFPAfile *file, char *exttype, psMetadata *hduHeader, psString extname, psArray *sources, long *sourceIndex) 
+{
+    if (!psFitsMoveExtName (file->fits, extname)) {
+        psError(PS_ERR_UNKNOWN, false, "cannot find extension %s in %s", extname, file->filename);
+        return false;
+    }
+
+    psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header
+    if (!tableHeader) psAbort("cannot read table header");
+
+    char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION");
+    if (!xtension) psAbort("cannot read table type");
+    if (strcmp (xtension, "BINTABLE")) {
+        psWarning ("no binary table in extension %s, skipping\n", extname);
+        return false;
+    }
+
+    // XXX these are case-sensitive since the EXTYPE is case-sensitive
+    bool status = false;
+    if (file->type == PM_FPA_FILE_CMF) {
+#ifdef notyet
+        if (!strcmp (exttype, "SMPDATA")) {
+            status  = pmSourcesRead_SMPDATA_XFIT (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DEV_0")) {
+            status  = pmSourcesRead_PS1_DEV_0_XFIT (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DEV_1")) {
+            status  = pmSourcesRead_PS1_DEV_1_XFIT (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V1")) {
+            status  = pmSourcesRead_CMF_PS1_V1_XFIT (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V2")) {
+            status  = pmSourcesRead_CMF_PS1_V2_XFIT (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V3")) {
+            status  = pmSourcesRead_CMF_PS1_V3_XFIT (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V4")) {
+            status  = pmSourcesRead_CMF_PS1_V4_XFIT (file->fits, hduHeader, sources);
+        }
+#endif // notyet
+        if (!strcmp (exttype, "PS1_SV1")) {
+            status  = pmSourcesRead_CMF_PS1_SV1_XFIT (file->fits, hduHeader, sources, sourceIndex);
+        }
+#ifdef notyet
+        if (!strcmp (exttype, "PS1_DV1")) {
+            status  = pmSourcesRead_CMF_PS1_DV1_XFIT (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DV2")) {
+            status  = pmSourcesRead_CMF_PS1_DV2_XFIT (file->fits, hduHeader, sources);
+        }
+#endif // notyet
+    }
+    psFree(tableHeader);
+    return status;
+}
+static bool pmReadoutReadXRAD(pmFPAfile *file, char *exttype, psMetadata *hduHeader, psString extname, psArray *sources, long *sourceIndex) 
+{
+    if (!psFitsMoveExtName (file->fits, extname)) {
+        psError(PS_ERR_UNKNOWN, false, "cannot find extension %s in %s", extname, file->filename);
+        return false;
+    }
+
+    psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header
+    if (!tableHeader) psAbort("cannot read table header");
+
+    char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION");
+    if (!xtension) psAbort("cannot read table type");
+    if (strcmp (xtension, "BINTABLE")) {
+        psWarning ("no binary table in extension %s, skipping\n", extname);
+        return false;
+    }
+
+    // XXX these are case-sensitive since the EXTYPE is case-sensitive
+    bool status = false;
+    if (file->type == PM_FPA_FILE_CMF) {
+#ifdef notyet
+        if (!strcmp (exttype, "SMPDATA")) {
+            status  = pmSourcesRead_SMPDATA_XRAD (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DEV_0")) {
+            status  = pmSourcesRead_PS1_DEV_0_XRAD (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DEV_1")) {
+            status  = pmSourcesRead_PS1_DEV_1_XRAD (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V1")) {
+            status  = pmSourcesRead_CMF_PS1_V1_XRAD (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V2")) {
+            status  = pmSourcesRead_CMF_PS1_V2_XRAD (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V3")) {
+            status  = pmSourcesRead_CMF_PS1_V3_XRAD (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_V4")) {
+            status  = pmSourcesRead_CMF_PS1_V4_XRAD (file->fits, hduHeader, sources);
+        }
+#endif // notyet
+        if (!strcmp (exttype, "PS1_SV1")) {
+            status  = pmSourcesRead_CMF_PS1_SV1_XRAD (file->fits, hduHeader, sources, sourceIndex);
+        }
+#ifdef notyet
+        if (!strcmp (exttype, "PS1_DV1")) {
+            status  = pmSourcesRead_CMF_PS1_DV1_XRAD (file->fits, hduHeader, sources);
+        }
+        if (!strcmp (exttype, "PS1_DV2")) {
+            status  = pmSourcesRead_CMF_PS1_DV2_XRAD (file->fits, hduHeader, sources);
+        }
+#endif // notyet
+    }
+    psFree(tableHeader);
+    return status;
+}
