Index: trunk/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 11144)
+++ trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 11182)
@@ -261,5 +261,5 @@
     psMetadata *format = NULL;
 
-    if (*found)
+    if (found && *found)
         return NULL;
 
@@ -411,4 +411,118 @@
 
 // search for argname on the config->argument list
+// construct an FPA based on the files in this list (must represent a single FPA)
+// built the association between the FPA elements (CHIP/CELL) and the files
+// define the pmFPAfile filename and bind it to this FPA
+// save the pmFPAfile on config->files
+// return the pmFPAfile (a view to the one saved on config->files)
+pmFPAfile *pmFPAfileBindFromArgs (bool *found, pmFPAfile *input, pmConfig *config, const char *filename, const char *argname)
+{
+    PS_ASSERT_PTR_NON_NULL(input, NULL);
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(argname, NULL);
+
+    bool status;
+    psFits *fits = NULL;
+    pmFPAfile *file = NULL;
+    psMetadata *phu = NULL;
+    psMetadata *format = NULL;
+
+    if (found && *found)
+        return NULL;
+
+    // we search the argument data for the named fileset (argname)
+    psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
+    if (!status) {
+        // this is not an error: this just means no matching argument was supplied
+        return NULL;
+    }
+    if (infiles->n < 1) {
+        psError(PS_ERR_IO, false, "Found n == %ld files in %s in arguments\n", infiles->n, argname);
+        return NULL;
+    }
+
+    // load the given filerule (from config->camera) and bind it to the fpa
+    // the returned file is just a view to the entry on config->files
+    file = pmFPAfileDefineInput (config, input->fpa, filename);
+    if (!file) {
+        psError(PS_ERR_IO, false, "file %s not defined\n", filename);
+        psFree(phu);
+        return NULL;
+    }
+    // XXX temporary hack : force PSF input onto filename
+    if (file->type == PM_FPA_FILE_PSF) {
+        file->filerule = psStringCopy (infiles->data[0]);
+        return file;
+    }
+
+    // set derived values
+    file->fileLevel = input->fileLevel;
+    file->format = psMemIncrRefCounter(input->format);
+
+    // defin the rule to identify these files in the file->names data
+    psFree (file->filerule);
+    psFree (file->filextra);
+    file->filerule = psStringCopy ("@FILES");
+    file->filextra = psStringCopy ("{CHIP.NAME}.{CELL.NAME}");
+
+    // examine the list of input files and validate their cameras
+    // associated each filename with an element of the FPA
+    // save the association on file->names
+    for (int i = 0; i < infiles->n; i++) {
+        psString realName = pmConfigConvertFilename (infiles->data[i], config);
+        if (!realName) {
+            psError(PS_ERR_IO, false, "Failed to convert file name %s", (char *) infiles->data[i]);
+            return NULL;
+        }
+        fits = psFitsOpen (realName, "r");
+        if (!fits) {
+            psError(PS_ERR_IO, false, "Failed to open file %s\n", realName);
+            psFree (realName);
+            return NULL;
+        }
+        phu = psFitsReadHeader (NULL, fits);
+        if (!phu) {
+            psError(PS_ERR_IO, false, "Failed to read file header %s", realName);
+            psFree (realName);
+            psFitsClose (fits);
+            return NULL;
+        }
+        if (!pmConfigValidateCameraFormat (format, phu)) {
+            psError(PS_ERR_IO, false, "specified MASK %s does not match format of supplied INPUT\n", realName);
+            psFree (realName);
+            psFitsClose (fits);
+            return NULL;
+        }
+        psFree(realName);
+        psFitsClose (fits);
+
+        // set the view to the corresponding entry for this phu
+        // XXX this will override the fpa->header, which I don't want to do.
+        // XXX do I need to carry around the mask and weight headers???
+        psAbort ("psModules", "pmFPAfileBindMaskFromArgs is not completed");
+        pmFPAview *view = pmFPAAddSourceFromHeader (input->fpa, phu, format);
+        if (!view) {
+            psError(PS_ERR_IO, false, "Unable to determine source for %s", file->name);
+            psFree(phu);
+            psFree (format);
+            return NULL;
+        }
+
+        // associate the filename with the FPA element
+        char *name = pmFPAfileNameFromRule (file->filextra, file, view);
+
+        // save the name association in the pmFPAfile structure
+        psMetadataAddStr (file->names, PS_LIST_TAIL, name, 0, "", infiles->data[i]);
+
+        psFree (view);
+        psFree (name);
+        psFree (phu);
+    }
+    *found = true;
+    return file;
+}
+
+// search for argname on the config->argument list
 // construct an FPA based on the files in this list (each represents the same FPA)
 // built the association between the FPA elements (CHIP/CELL) and the files
@@ -430,5 +544,5 @@
     psMetadata *format = NULL;
 
-    if (*found)
+    if (found && *found)
         return NULL;
 
@@ -536,7 +650,6 @@
     PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
 
-    if (*found) {
-        return NULL;
-    }
+    if (found && *found)
+        return NULL;
 
     // a camera config is needed (as source of file rule)
@@ -613,5 +726,5 @@
     pmFPAfile *file = NULL;
 
-    if (*found)
+    if (found && *found)
         return NULL;
 
