Index: /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.c	(revision 6818)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.c	(revision 6819)
@@ -67,5 +67,5 @@
 }
 
-pmFPAfile *pmFPAfileDefine (psMetadata *files, psMetadata *format, pmFPA *fpa, char *name)
+pmFPAfile *pmFPAfileDefine (psMetadata *files, psMetadata *camera, pmFPA *fpa, char *name)
 {
 
@@ -74,13 +74,13 @@
     char *type;
 
-    // select the FILERULES from the camera format
-    psMetadata *filerules = psMetadataLookupPtr (&status, format, "FILERULES");
+    // select the FILERULES from the camera config
+    psMetadata *filerules = psMetadataLookupPtr (&status, camera, "FILERULES");
     if (filerules == NULL) {
-        psErrorStackPrint(stderr, "Can't find FILERULES in the FORMAT configuration!\n");
+        psErrorStackPrint(stderr, "Can't find FILERULES in the CAMERA configuration!\n");
         return NULL;
     }
 
     // select the name from the FILERULES
-    // check for indirect name (type == STR, name is aliased name)
+    // check for alias name (type == STR, name is aliased name)
     char *realname = psMetadataLookupStr (&status, filerules, name);
     if (realname == NULL)
@@ -179,5 +179,7 @@
     }
 
-    file->fpa = psMemIncrRefCounter(fpa);
+    if (fpa != NULL) {
+        file->fpa = psMemIncrRefCounter(fpa);
+    }
 
     psMetadataAddPtr (files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN, "", file);
@@ -190,4 +192,5 @@
 }
 
+/*
 pmFPAfile *pmFPAfileConstruct (psMetadata *files, psMetadata *format, psMetadata *camera, char *name)
 {
@@ -197,4 +200,5 @@
     return file;
 }
+*/
 
 // open file (if not already opened)
@@ -228,5 +232,5 @@
 
     // indirect filenames
-    if (!strcasecmp (file->filename, "@FPAIO")) {
+    if (!strcasecmp (file->filename, "@FILES")) {
         psFree (file->filename);
         extra = pmFPAfileNameFromRule (file->filextra, file, view);
@@ -252,6 +256,8 @@
     case PM_FPA_FILE_IMAGE:
     case PM_FPA_FILE_CMF:
+        psTrace ("pmFPAfile", 5, "opening %s (type: %d)\n", file->filename, file->type);
         file->fits = psFitsOpen (file->filename, mode);
-        psTrace ("pmFPAfile", 5, "opening %s (type: %d)\n", file->filename, file->type);
+        if (file->fits == NULL)
+            psAbort (__func__, "error opening file %s\n", file->filename);
         file->state = PM_FPA_STATE_OPEN;
         break;
@@ -410,45 +416,4 @@
     psFree (iter);
     return true;
-}
-
-// select the rule from the camera configuration, perform substitutions as needed
-char *pmFPAfileNameFromRule (char *rule, pmFPAfile *file, const pmFPAview *view)
-{
-
-    char *newName = NULL;     // destination for resulting name
-
-    newName = psStringCopy (rule);
-
-    if (strstr (newName, "{CHIP.NAME}") != NULL) {
-        pmChip *chip = pmFPAviewThisChip (view, file->fpa);
-        if (chip != NULL) {
-            char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
-            if (name != NULL) {
-                newName = psStringSubstitute (newName, name, "{CHIP.NAME}");
-            }
-        }
-    }
-    if (strstr (newName, "{CELL.NAME}") != NULL) {
-        pmCell *cell = pmFPAviewThisCell (view, file->fpa);
-        if (cell != NULL) {
-            char *name = psMetadataLookupStr (NULL, cell->concepts, "CELL.NAME");
-            if (name != NULL) {
-                newName = psStringSubstitute (newName, name, "{CELL.NAME}");
-            }
-        }
-    }
-    if (strstr (newName, "{EXTNAME}") != NULL) {
-        pmHDU *hdu = pmFPAviewThisHDU (view, file->fpa);
-        if (hdu->extname != NULL) {
-            newName = psStringSubstitute (newName, hdu->extname, "{EXTNAME}");
-        }
-    }
-    if (strstr (newName, "{OUTPUT}") != NULL) {
-        char *name = psMetadataLookupStr (NULL, file->names, "OUTPUT");
-        if (name != NULL) {
-            newName = psStringSubstitute (newName, name, "{OUTPUT}");
-        }
-    }
-    return newName;
 }
 
@@ -606,2 +571,229 @@
     # endif
 }
+
+// look for the given name on the argument list.
+// returns the file (a view to the one saved on config->files)
+pmFPAfile *pmFPAfileFromArgs (bool *found, pmConfig *config, char *filename, char *argname)
+{
+    bool status;
+    pmFPA *fpa = NULL;
+    psFits *fits = NULL;
+    pmFPAfile *file = NULL;
+    psMetadata *phu = NULL;
+    psMetadata *format = NULL;
+
+    if (*found)
+        return NULL;
+
+    // we search the argument data for the named fileset (argname)
+    psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
+    if (!status)
+        return NULL;
+    if (infiles->n < 1)
+        return NULL;
+
+    // determine the current format from the header
+    // if no camera has been specified, use the first image as a template for the rest.
+    fits = psFitsOpen (infiles->data[0], "r");
+    phu = psFitsReadHeader (NULL, fits);
+    format = pmConfigCameraFormatFromHeader (config, phu);
+    psFitsClose (fits);
+
+    // build the template fpa, set up the basic view
+    fpa = pmFPAConstruct (config->camera);
+
+    // load the given filerule (from config->camera) and associate it with the fpa
+    // the output file is just a view to the file on config->files
+    file = pmFPAfileDefine (config->files, config->camera, fpa, filename);
+    if (!file) {
+        psErrorStackPrint(stderr, "file %s not defined\n", filename);
+        psFree (fpa);
+        psFree (format);
+        return NULL;
+    }
+
+    // this file is (by virtue of being supplied in the argument list) coming from the fileset
+    psFree (file->filerule);
+    psFree (file->filextra);
+
+    // adjust the rules to identify these files in the file->names data
+    file->filerule = psStringCopy ("@FILES");
+    // XXX this rule does not work in general
+    file->filextra = psStringCopy ("{CHIP.NAME}.{CELL.NAME}");
+
+    // examine the list of input files and validate their cameras
+    for (int i = 0; i < infiles->n; i++) {
+        if (i > 0) {
+            fits = psFitsOpen (infiles->data[i], "r");
+            phu = psFitsReadHeader (NULL, fits);
+            pmConfigValidateCameraFormat (format, phu);
+            psFitsClose (fits);
+        }
+
+        // set the view to the corresponding entry for this phu
+        pmFPAview *view = pmFPAAddSource (fpa, phu, format);
+
+        // XXX is this the correct psMD to save the filename?
+        char *name = pmFPAfileNameFromRule (file->filextra, file, view);
+        psMetadataAddStr (file->names, PS_LIST_TAIL, name, 0, "", infiles->data[i]);
+
+        psFree (view);
+        psFree (name);
+        psFree (phu);
+    }
+    psFree (fpa);
+    psFree (format);
+    *found = true;
+
+    return file;
+}
+
+// look for the given name on the argument list.
+pmFPAfile *pmFPAfileFromConf (bool *found, pmConfig *config, char *filename, pmFPA *input)
+{
+    psFits *fits = NULL;
+    pmFPAfile *file = NULL;
+    psMetadata *phu = NULL;
+    psMetadata *format = NULL;
+    psArray *infiles = NULL;
+
+    if (*found)
+        return NULL;
+
+    // a camera config is needed (as source of file rule)
+    if (config->camera == NULL) {
+        psErrorStackPrint (stderr, "camera is not defined\n");
+        return NULL;
+    }
+
+    // expect @DETDB in the config filerule
+    file = pmFPAfileDefine (config->files, config->camera, NULL, filename);
+    if (!file) {
+        psErrorStackPrint(stderr, "file %s not defined\n", filename);
+        return NULL;
+    }
+
+    // image names come from the file->name list?
+    if (!strcasecmp (file->filerule, "@FILES"))
+        psAbort ("pmFPAfileFromConfig", "programming error");
+
+    // image needs to come from the detrend database
+    if (!strcasecmp (file->filerule, "@DETDB")) {
+        // char *extra = pmFPAfileNameFromRule (file->filextra, file, view);
+        // psArray *infiles = pmDetrendSelect (extra, input);
+        psAbort ("pmFPAfileFromConfig", "@DETDB not yet defined");
+    } else {
+        infiles = psArrayAlloc(1);
+        infiles->n = 1;
+        infiles->data[0] = psStringCopy (file->filerule);
+    }
+    if (infiles == NULL)
+        return NULL;
+    if (infiles->n < 1) {
+        psFree (infiles);
+        return NULL;
+    }
+
+    // determine the current format from the header
+    // if no camera has been specified, use the first image as a template for the rest.
+    fits = psFitsOpen (infiles->data[0], "r");
+    phu = psFitsReadHeader (NULL, fits);
+    format = pmConfigCameraFormatFromHeader (config, phu);
+    psFitsClose (fits);
+
+    // build the template fpa, set up the basic view
+    file->fpa = pmFPAConstruct (config->camera);
+
+    // this file is (by virtue of being supplied in the argument list) coming from the fileset
+    psFree (file->filerule);
+    psFree (file->filextra);
+
+    // adjust the rules to identify these files in the file->names data
+    file->filerule = psStringCopy ("@FILES");
+    // XXX this rule does not work in general
+    file->filextra = psStringCopy ("{CHIP.NAME}.{CELL.NAME}");
+
+    // examine the list of input files and validate their cameras
+    for (int i = 0; i < infiles->n; i++) {
+        if (i > 0) {
+            fits = psFitsOpen (infiles->data[i], "r");
+            phu = psFitsReadHeader (NULL, fits);
+            pmConfigValidateCameraFormat (format, phu);
+            psFitsClose (fits);
+        }
+
+        // set the view to the corresponding entry for this phu
+        pmFPAview *view = pmFPAAddSource (file->fpa, phu, format);
+
+        // XXX is this the correct psMD to save the filename?
+        char *name = pmFPAfileNameFromRule (file->filextra, file, view);
+        psMetadataAddStr (file->names, PS_LIST_TAIL, name, 0, "", infiles->data[i]);
+
+        psFree (view);
+        psFree (name);
+        psFree (phu);
+    }
+    psFree (format);
+    psFree (infiles);
+    *found = true;
+    return file;
+}
+
+bool pmFPAfileAddFileNames (psMetadata *files, char *name, char *value, int mode)
+{
+
+    // add the output names to the output-type files
+    psMetadataItem *item = NULL;
+    psMetadataIterator *iter = psMetadataIteratorAlloc (files, PS_LIST_HEAD, NULL);
+    while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
+        pmFPAfile *file = item->data.V;
+
+        if (file->mode == mode) {
+            psMetadataAddStr (file->names, PS_LIST_TAIL, name, 0, "", value);
+        }
+    }
+    psFree (iter);
+    return true;
+}
+
+// select the rule from the camera configuration, perform substitutions as needed
+char *pmFPAfileNameFromRule (char *rule, pmFPAfile *file, const pmFPAview *view)
+{
+
+    char *newName = NULL;     // destination for resulting name
+
+    newName = psStringCopy (rule);
+
+    if (strstr (newName, "{CHIP.NAME}") != NULL) {
+        pmChip *chip = pmFPAviewThisChip (view, file->fpa);
+        if (chip != NULL) {
+            char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
+            if (name != NULL) {
+                newName = psStringSubstitute (newName, name, "{CHIP.NAME}");
+            }
+        }
+    }
+    if (strstr (newName, "{CELL.NAME}") != NULL) {
+        pmCell *cell = pmFPAviewThisCell (view, file->fpa);
+        if (cell != NULL) {
+            char *name = psMetadataLookupStr (NULL, cell->concepts, "CELL.NAME");
+            if (name != NULL) {
+                newName = psStringSubstitute (newName, name, "{CELL.NAME}");
+            }
+        }
+    }
+    if (strstr (newName, "{EXTNAME}") != NULL) {
+        pmHDU *hdu = pmFPAviewThisHDU (view, file->fpa);
+        if (hdu->extname != NULL) {
+            newName = psStringSubstitute (newName, hdu->extname, "{EXTNAME}");
+        }
+    }
+    if (strstr (newName, "{OUTPUT}") != NULL) {
+        char *name = psMetadataLookupStr (NULL, file->names, "OUTPUT");
+        if (name != NULL) {
+            newName = psStringSubstitute (newName, name, "{OUTPUT}");
+        }
+    }
+    return newName;
+}
+
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.h	(revision 6818)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.h	(revision 6819)
@@ -7,6 +7,6 @@
 *  @author EAM, IfA
 *
-*  @version $Revision: 1.1.2.8 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-03-29 20:55:42 $
+*  @version $Revision: 1.1.2.9 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-04-08 20:13:03 $
 *
 *  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
@@ -17,4 +17,5 @@
 
 #include "pslib.h"
+#include "pmConfig.h"
 #include "pmFPA.h"
 #include "pmFPAview.h"
@@ -72,14 +73,31 @@
 pmFPAfile;
 
+// allocate an empty pmFPAfile structure
 pmFPAfile *pmFPAfileAlloc ();
+
+// load the pmFPAfile information from the camera configuration data
 pmFPAfile *pmFPAfileDefine (psMetadata *files, psMetadata *camera, pmFPA *fpa, char *name);
+
+// load the pmFPAfile information from the camera configuration data, constructing the needed fpa structure
+// XXX deprecate this function?
+pmFPAfile *pmFPAfileConstruct (psMetadata *files, psMetadata *format, psMetadata *camera, char *name);
+
+// open the real file corresponding to the given pmFPAfile appropriate to the current view
 bool pmFPAfileOpen (pmFPAfile *file, const pmFPAview *view);
+
+// read from the real file corresponding to the given pmFPAfile for the current view
 bool pmFPAfileRead (pmFPAfile *file, const pmFPAview *view);
+
+// write to the real file corresponding to the given pmFPAfile for the current view
 bool pmFPAfileWrite (pmFPAfile *file, const pmFPAview *view);
+
+// close the real file corresponding to the given pmFPAfile appropriate to the current view
 bool pmFPAfileClose (pmFPAfile *file, const pmFPAview *view);
 
-bool pmFPAfileReadChecks (psMetadata *files, const pmFPAview *view);
+// examine all pmFPAfiles listed in the files and perform the needed I/O operations (open,read,write,close)
 bool pmFPAfileIOChecks (psMetadata *files, const pmFPAview *view, pmFPAfilePlace place);
 
+// return an image corresponding to the current readout, from the specified file.  if the pmFPAfile does not
+// exist, construct the image using the given size and type (save it in a pmFPAfile??)
 psImage *pmFPAfileReadoutImage (psMetadata *files, const pmFPAview *view, char *name, int Nx, int Ny, int type);
 
@@ -90,8 +108,15 @@
 bool pmFPAviewWriteFitsImage (const pmFPAview *view, pmFPAfile *file);
 
+// look for the given argname on the argument list.  find the give filename from the file rules
+pmFPAfile *pmFPAfileFromArgs (bool *found, pmConfig *config, char *filename, char *argname);
+
+// look for the given argname on the argument list.  find the give filename from the file rules
+pmFPAfile *pmFPAfileFromConf (bool *found, pmConfig *config, char *filename, pmFPA *input);
+
+// add the specified filename info (value) to the files of the given mode using the given reference name
+bool pmFPAfileAddFileNames (psMetadata *files, char *name, char *value, int mode);
+
 // convert the rule to a name based on the current view
 char *pmFPAfileNameFromRule (char *rule, pmFPAfile *file, const pmFPAview *view);
 
-pmFPAfile *pmFPAfileConstruct (psMetadata *files, psMetadata *format, psMetadata *camera, char *name);
-
 # endif
Index: /branches/rel10_ifa/psModules/src/config/pmConfig.c
===================================================================
--- /branches/rel10_ifa/psModules/src/config/pmConfig.c	(revision 6818)
+++ /branches/rel10_ifa/psModules/src/config/pmConfig.c	(revision 6819)
@@ -3,6 +3,6 @@
  *  @author PAP, IfA
  *
- *  @version $Revision: 1.7.4.9 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-04-04 22:14:58 $
+ *  @version $Revision: 1.7.4.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-04-08 20:13:03 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -15,4 +15,5 @@
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <glob.h>
 #include "pslib.h"
 #include "pmConfig.h"
@@ -40,5 +41,4 @@
     // Initialise
     config->site = NULL;
-    config->files = NULL;
     config->camera = NULL;
     config->recipes = NULL;
@@ -46,4 +46,6 @@
     config->database = NULL;
 
+    // the file structure is used to carry pmFPAfiles
+    config->files = psMetadataAlloc ();
     return config;
 }
@@ -656,2 +658,75 @@
     return true;
 }
+
+// given the 'file' and 'list' words, find the arguments associated with these words
+// and interpret them as lists of files.  return an array of the resulting filenames.
+psArray *pmConfigFileSets (int *argc, char **argv, char *file, char *list)
+{
+
+    int Narg;
+
+    // we load all input files onto a psArray, to be parsed later
+    psArray *input = psArrayAlloc (16);
+    input->n = 0;
+
+    // load the list of filenames the supplied file (may be a glob: "file*.fits")
+    if ((Narg = psArgumentGet (*argc, argv, file))) {
+        glob_t globList;
+        psArgumentRemove (Narg, argc, argv);
+        globList.gl_offs = 0;
+        glob (argv[Narg], 0, NULL, &globList);
+        for (int i = 0; i < globList.gl_pathc; i++) {
+            char *filename = psStringCopy (globList.gl_pathv[i]);
+            psArrayAdd (input, 16, filename);
+            psFree (filename);
+        }
+        psArgumentRemove (Narg, argc, argv);
+    }
+
+    // load the list from the supplied text file
+    if ((Narg = psArgumentGet (*argc, argv, list))) {
+        int nItems;
+        char line[1024]; // XXX limits the list lines to 1024 chars
+        char word[1024];
+        char *filename;
+
+        psArgumentRemove (Narg, argc, argv);
+        FILE *f = fopen (argv[Narg], "r");
+        if (f == NULL) {
+            psAbort ("psphot", "unable to open specified list file");
+        }
+        while (fgets (line, 1024, f) != NULL) {
+            nItems = sscanf (line, "%s", word);
+            switch (nItems) {
+            case 0:
+                break;
+            case 1:
+                filename = psStringCopy (word);
+                psArrayAdd (input, 16, filename);
+                psFree (filename);
+                break;
+            default:
+                // rigid format, no comments allowed?
+                psAbort ("pmConfig", "error parsing input list file");
+                break;
+            }
+        }
+        psArgumentRemove (Narg, argc, argv);
+    }
+
+    return input;
+}
+
+bool pmConfigFileSetsMD (psMetadata *metadata, int *argc, char **argv, char *name, char *file, char *list)
+{
+
+    psArray *files = pmConfigFileSets (argc, argv, file, list);
+    if (files->n == 0) {
+        psFree (files);
+        return false;
+    }
+
+    psMetadataAddPtr (metadata, PS_LIST_TAIL, name,  PS_DATA_ARRAY, "", files);
+    psFree (files);
+    return true;
+}
Index: /branches/rel10_ifa/psModules/src/config/pmConfig.h
===================================================================
--- /branches/rel10_ifa/psModules/src/config/pmConfig.h	(revision 6818)
+++ /branches/rel10_ifa/psModules/src/config/pmConfig.h	(revision 6819)
@@ -3,6 +3,6 @@
  *  @author PAP, IfA
  *
- *  @version $Revision: 1.3.4.6 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-04-04 22:14:58 $
+ *  @version $Revision: 1.3.4.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-04-08 20:13:03 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -23,4 +23,5 @@
     psMetadata *arguments;              // Command-line arguments
     psMetadata *files;                  // pmFPAfiles used for analysis
+    //    psMetadata *format;   // camera format for primary image
     psDB *database;                     // Database handle
 }
@@ -112,3 +113,7 @@
 
 
+psArray *pmConfigFileSets (int *argc, char **argv, char *file, char *list);
+bool pmConfigFileSetsMD (psMetadata *metadata, int *argc, char **argv, char *name, char *file, char *list);
+
+
 #endif
