Index: /branches/eam_branches/ipp-20130307/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- /branches/eam_branches/ipp-20130307/psModules/src/camera/pmFPAfileDefine.c	(revision 35378)
+++ /branches/eam_branches/ipp-20130307/psModules/src/camera/pmFPAfileDefine.c	(revision 35379)
@@ -446,7 +446,131 @@
 }
 
+// given a filename, convert to UNIX namespace and read the PHU 
+psMetadata *readPHUfromFilename (char *filename, pmConfig *config) {
+
+    // Need to generate an FPA
+    psString realName = pmConfigConvertFilename(filename, config, false, false);
+    if (!realName) {
+	psError(psErrorCodeLast(), false, "Failed to convert file name %s", filename);
+	return NULL;
+    }
+
+    // load the header of the first image
+    // EXTWORD (fits->extword) is not relevant to the PHU
+    psFits *fits = psFitsOpen(realName, "r"); // FITS file
+    if (!fits) {
+	psError(psErrorCodeLast(), false, "Failed to open file %s", realName);
+	psFree(realName);
+	return NULL;
+    }
+
+    psMetadata *phu = psFitsReadHeader (NULL, fits); // Primary header
+    if (!phu) {
+	psError(psErrorCodeLast(), false, "Failed to read file header %s", realName);
+	psFree(realName);
+	return NULL;
+    }
+
+    if (!psFitsClose(fits)) {
+	psError(psErrorCodeLast(), false, "Failed to close file %s", realName);
+	psFree(realName);
+	psFree(phu);
+	return NULL;
+    }
+
+    return phu;
+}
+
+// this this function wants to return:
+// pmFPA, PHU, fileLevel, outConfig
+// camera, cameraName, formatName
+typedef struct {
+    pmFPA *fpa;
+    psMetadata *phu;
+    psMetadata *format;
+    pmFPALevel fileLevel;
+    psString cameraName;
+    psString formatName;
+} pmFPAfromFilenameOutput;
+
+// for the given filename, read PHU and determine camera format; build an FPA for the file
+bool pmFPAfromFilename (pmFPAfromFilenameOutput *output, pmConfig **outConfig, pmConfig *sysConfig, char *filename){
+
+    // Need to generate an FPA
+    psMetadata *phu = readPHUfromFilename (filename, sysConfig);
+    if (!phu) {
+	psError(psErrorCodeLast(), false, "Failed to read PHU for %s", filename);
+	return false;
+    }
+
+    // if we expect the loaded FPA to differ in configuration from the current system configuration
+    // generate an output config for this FPA
+    pmConfig *config = NULL;
+    if (outConfig) {
+	config = pmConfigAlloc();
+	config->user = psMemIncrRefCounter(sysConfig->user);
+	config->system = psMemIncrRefCounter(sysConfig->system);
+
+	psFree (config->files);
+	config->files = psMemIncrRefCounter(sysConfig->files);
+	psFree (config->arguments);
+	config->arguments = psMemIncrRefCounter(sysConfig->arguments);
+
+	*outConfig = config;
+    } else {
+	config = sysConfig;
+    }
+
+    // values which are returned to calling function
+    psString formatName = NULL;	// Name of camera format
+    psString cameraName = NULL;	// Name of camera
+    psMetadata *camera = NULL;	// Camera configuration
+
+    // Determine the current format from the header; determine camera if not specified already.
+    psMetadata *format = pmConfigCameraFormatFromHeader(&camera, &cameraName, &formatName, config, phu, true);
+    if (!format) {
+	psError(psErrorCodeLast(), false, "Failed to determine camera format for %s", filename);
+	psFree(camera);
+	psFree(formatName);
+	psFree(phu);
+	return false;
+    }
+
+    pmFPALevel fileLevel = pmFPAPHULevel(format);
+    if (fileLevel == PM_FPA_LEVEL_NONE) {
+	psError(PM_ERR_CONFIG, true, "Unable to determine file level for %s", filename);
+	psFree(camera);
+	psFree(formatName);
+	psFree(phu);
+	return false;
+    }
+
+    // build the template fpa, set up the basic view
+    // we supply the metaCamera name (if NULL, baseCamera name is used)
+    pmFPA *fpa = pmFPAConstruct(camera, cameraName);
+    psFree(camera);
+
+    if (!fpa) {
+	psError(psErrorCodeLast(), false, "Failed to construct FPA from %s", filename);
+	psFree(formatName);
+	psFree(format);
+	psFree(phu);
+	return NULL;
+    }
+
+    output->fpa = fpa;
+    output->phu = phu;
+    output->format = format;
+    output->fileLevel = fileLevel;
+    output->cameraName = cameraName;
+    output->formatName = formatName;
+
+    return true;
+
+}
 
 /// Define a file from an array of filenames
-static pmFPAfile *fpaFileDefineFromArray(pmConfig *config, // Configuration
+static pmFPAfile *fpaFileDefineFromArray(pmConfig **outConfig, // output configuration
+					 pmConfig *sysConfig, // global configuration
                                          pmFPAfile *bind, // File to bind to, or NULL
                                          const char *name, // Name of file
@@ -454,5 +578,5 @@
     )
 {
-    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(sysConfig, NULL);
     PS_ASSERT_STRING_NON_EMPTY(name, NULL);
 
@@ -463,4 +587,5 @@
     pmFPALevel fileLevel = PM_FPA_LEVEL_NONE; // Level for files
     psMetadata *phu = NULL;             // Primary header
+
     if (bind) {
         // Use the FPA we're binding to
@@ -468,67 +593,17 @@
         fileLevel = bind->fileLevel;
     } else {
-        // Need to generate an FPA
-        psString realName = pmConfigConvertFilename(filenames->data[0], config, false, false);
-        if (!realName) {
-            psError(psErrorCodeLast(), false, "Failed to convert file name %s", (char *)filenames->data[0]);
-            return NULL;
-        }
-
-        // load the header of the first image
-        // EXTWORD (fits->extword) is not relevant to the PHU
-        psFits *fits = psFitsOpen(realName, "r"); // FITS file
-        if (!fits) {
-            psError(psErrorCodeLast(), false, "Failed to open file %s", realName);
-            psFree(realName);
-            return NULL;
-        }
-        phu = psFitsReadHeader (NULL, fits); // Primary header
-        if (!phu) {
-            psError(psErrorCodeLast(), false, "Failed to read file header %s", realName);
-            psFree(realName);
-            return NULL;
-        }
-        if (!psFitsClose(fits)) {
-            psError(psErrorCodeLast(), false, "Failed to close file %s", realName);
-            psFree(realName);
-            return NULL;
-        }
-
-        // Determine the current format from the header; determine camera if not specified already.
-        psMetadata *camera = NULL;      // Camera configuration
-        format = pmConfigCameraFormatFromHeader(&camera, &cameraName, &formatName, config, phu, true);
-        if (!format) {
-            psError(psErrorCodeLast(), false, "Failed to determine camera format for %s", realName);
-            psFree(camera);
-            psFree(formatName);
-            psFree(realName);
-            psFree(phu);
-            return NULL;
-        }
-
-        fileLevel = pmFPAPHULevel(format);
-        if (fileLevel == PM_FPA_LEVEL_NONE) {
-            psError(PM_ERR_CONFIG, true, "Unable to determine file level for %s", realName);
-            psFree(camera);
-            psFree(formatName);
-            psFree(realName);
-            psFree(phu);
-            return NULL;
-        }
-
-        // build the template fpa, set up the basic view
-        // XXX do we want this to be the baseCamera name or the metaCamera name?
-        fpa = pmFPAConstruct(camera, cameraName);
-        psFree(camera);
-        if (!fpa) {
-            psError(psErrorCodeLast(), false, "Failed to construct FPA from %s", realName);
-            psFree(formatName);
-            psFree(realName);
-            psFree(format);
-            psFree(phu);
-            return NULL;
-        }
-        psFree(realName);
-    }
+	pmFPAfromFilenameOutput output;
+	if (!pmFPAfromFilename (&output, outConfig, sysConfig, filenames->data[0])) {
+	    return NULL;
+	}
+	fpa = output.fpa;
+	phu = output.phu;
+	format = output.format;
+	fileLevel = output.fileLevel;
+	cameraName = output.cameraName;
+	formatName = output.formatName;
+    }
+
+    pmConfig *config = outConfig ? *outConfig : sysConfig;
 
     // load the given filerule (from config->camera) and bind it to the fpa
@@ -561,27 +636,9 @@
         // Check that the file corresponds to the same camera and format
         if (!phu) {
-            psString realName = pmConfigConvertFilename(filenames->data[i], config, false, false);
-            if (!realName) {
-                psError(psErrorCodeLast(), false, "Failed to convert file name %s", (char*)filenames->data[i]);
+	    phu = readPHUfromFilename (filenames->data[i], config);
+            if (!phu) {
+                psError(psErrorCodeLast(), false, "Failed to read PHU for %s", (char *)filenames->data[i]);
                 return NULL;
             }
-            psFits *fits = psFitsOpen(realName, "r"); // FITS file
-            if (!fits) {
-                psError(psErrorCodeLast(), false, "Failed to open file %s", realName);
-                psFree(realName);
-                return NULL;
-            }
-            phu = psFitsReadHeader(NULL, fits);
-            if (!psFitsClose(fits)) {
-                psError(psErrorCodeLast(), false, "Failed to close file %s", realName);
-                psFree(realName);
-                return NULL;
-            }
-            if (!phu) {
-                psError(psErrorCodeLast(), false, "Failed to read file header %s", realName);
-                psFree(realName);
-                return NULL;
-            }
-            psFree(realName);
         }
 
@@ -676,5 +733,5 @@
     }
 
-    pmFPAfile *file = fpaFileDefineFromArray(config, NULL, filename, filenames); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, NULL, filename, filenames); // File of interest
 
     if (success) {
@@ -710,5 +767,5 @@
     }
 
-    pmFPAfile *file = fpaFileDefineFromArray(config, input, filename, filenames); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, input, filename, filenames); // File of interest
 
     if (success) {
@@ -746,5 +803,5 @@
     psArray *single = psArrayAlloc(1);  // Array of single filename of interest
     single->data[0] = psMemIncrRefCounter(filenames->data[entry]);
-    pmFPAfile *file = fpaFileDefineFromArray(config, NULL, filename, single); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, NULL, filename, single); // File of interest
     psFree(single);
 
@@ -769,5 +826,5 @@
     }
 
-    pmFPAfile *file = fpaFileDefineFromArray(config, bind, filename, filenames); // File of interest
+    pmFPAfile *file = fpaFileDefineFromArray(NULL, config, bind, filename, filenames); // File of interest
     psFree(filenames);
 
@@ -808,5 +865,5 @@
         dummy->data[0] = files->data[i];
         pmFPAfile *bindFile = bind ? bind->data[i] : NULL; // File to which to bind
-        files->data[i] = psMemIncrRefCounter(fpaFileDefineFromArray(config, bindFile, filename, dummy));
+        files->data[i] = psMemIncrRefCounter(fpaFileDefineFromArray(NULL, config, bindFile, filename, dummy));
         if (!files->data[i]) {
             psError(psErrorCodeLast(), false, "Unable to define file %s %d", filename, i);
