Index: branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfile.c
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfile.c	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfile.c	(revision 27648)
@@ -111,5 +111,6 @@
     file->save = false;
 
-    file->index = fileNum++;
+    file->fileIndex = fileNum++;
+    file->fileID = 0;
 
     file->imageId = 0;
@@ -372,6 +373,14 @@
         // Number of the file in list
         psString num = NULL;            // Number to use
-        psStringAppend(&num, "%d", file->index);
+        psStringAppend(&num, "%d", file->fileIndex);
         psStringSubstitute(&newRule, num, "{FILE.INDEX}");
+        psFree(num);
+    }
+
+    if (strstr(newRule, "{FILE.ID}")) {
+        // Number of the file in list
+        psString num = NULL;            // Number to use
+        psStringAppend(&num, "%03d", file->fileID);
+        psStringSubstitute(&newRule, num, "{FILE.ID}");
         psFree(num);
     }
@@ -638,5 +647,5 @@
     psFree(iter);
 
-    psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to find instance %d of file %s", num, name);
+    psLogMsg("psModules.camera", PS_LOG_MINUTIA, "Unable to find instance %d of file %s", num, name);
     return NULL;
 }
Index: branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfile.h
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfile.h	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfile.h	(revision 27648)
@@ -111,5 +111,6 @@
     psString formatName;                // name of the camera format
 
-    int index;                          // Index of file
+    int fileIndex;			// Index of file
+    int fileID;				// internal sequence number
 
     psS64 imageId, sourceId;            // Image and source identifiers
Index: branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfileDefine.c	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfileDefine.c	(revision 27648)
@@ -1271,6 +1271,11 @@
     file->name = psStringCopy (name);
 
+    // free a previously existing readout
+    psFree(file->readout);
     file->readout = readout;
-    psMetadataAddPtr(files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN, "", file);
+
+    // allow for multiple entries
+    // XXX handle replace vs multiple?
+    psMetadataAddPtr(files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "", file);
     psFree(file);
     // we free this copy of file, but 'files' still has a copy
@@ -1313,14 +1318,16 @@
                                 const char *name, // name of internal/external file
                                 const pmFPA *fpa, // use this fpa to generate
-                                const psImageBinning *binning) {
+                                const psImageBinning *binning,
+                                int index) {
   pmReadout *readout = NULL;
 
-  bool status = true;
-  pmFPAfile *file = psMetadataLookupPtr(&status, config->files, name);
+  pmFPAfile *file = pmFPAfileSelectSingle(config->files, name, index);
 
   // if the file does not exist, it is not being used as an I/O file: define an internal version
   if (file == NULL) {
-    readout = pmFPAfileDefineInternal (config->files, name, binning->nXruff, binning->nYruff, PS_TYPE_F32);
-    return readout;
+      // XXX currently, we do not guarantee that the defined file lands on entry 'index'
+      psAssert (binning, "internal files must be supplied a psImageBinning for the output images size"); 
+      readout = pmFPAfileDefineInternal (config->files, name, binning->nXruff, binning->nYruff, PS_TYPE_F32);
+      return readout;
   }
 
Index: branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfileDefine.h
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfileDefine.h	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/camera/pmFPAfileDefine.h	(revision 27648)
@@ -172,5 +172,7 @@
                                 const char *name, // name of internal/external file
                                 const pmFPA *fpa, // use this fpa to generate
-                                const psImageBinning *binning);
+                                const psImageBinning *binning,
+				int index
+    );
 
 /// @}
Index: branches/eam_branches/stackphot.20100406/psModules/src/objects/Makefile.am
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/objects/Makefile.am	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/objects/Makefile.am	(revision 27648)
@@ -20,4 +20,5 @@
 	pmModelUtils.c \
 	pmSource.c \
+	pmPhotObj.c \
 	pmSourceMasks.c \
 	pmSourceMoments.c \
@@ -80,4 +81,5 @@
 	pmModelUtils.h \
 	pmSource.h \
+	pmPhotObj.h \
 	pmSourceMasks.h \
 	pmSourceDiffStats.h \
Index: branches/eam_branches/stackphot.20100406/psModules/src/objects/pmPhotObj.c
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/objects/pmPhotObj.c	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/objects/pmPhotObj.c	(revision 27648)
@@ -17,4 +17,5 @@
 #include <pslib.h>
 #include "pmPhotObj.h"
+#include "pmSource.h"
 
 static void pmPhotObjFree (pmPhotObj *tmp)
@@ -38,2 +39,27 @@
 }
 
+bool pmPhotObjAddSource(pmPhotObj *object, pmSource *source) {
+
+    psAssert (source, "programming error: NULL source");
+    if (!source->peak) {
+	psError(PS_ERR_UNKNOWN, true, "source missing peak");
+	return false; 
+    }
+    if (!finite(source->peak->xf)) {
+	psError(PS_ERR_UNKNOWN, true, "NAN peak coordinate");
+	return false; 
+    }
+    if (!finite(source->peak->yf)) {
+	psError(PS_ERR_UNKNOWN, true, "NAN peak coordinate");
+	return false; 
+    }
+
+    // XXX we should probably use the fitted position if it exists
+    if (!object->sources) {
+	object->sources = psArrayAllocEmpty(1);
+	object->x = source->peak->xf;
+	object->y = source->peak->yf;
+    }
+    psArrayAdd (object->sources, 1, source);
+    return true;
+}
Index: branches/eam_branches/stackphot.20100406/psModules/src/objects/pmPhotObj.h
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/objects/pmPhotObj.h	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/objects/pmPhotObj.h	(revision 27648)
@@ -34,9 +34,15 @@
  */
 typedef struct {
-  int seq;                            ///< ID for output (generated on write OR set on read)
-  psArray *sources;
-  int flags;
+    int id;                            ///< ID for output (generated on write OR set on read)
+    psArray *sources;
+    int flags;
+    float x;
+    float y;
 } pmPhotObj;
+
+bool pmPhotObjAddSource(pmPhotObj *object, pmSource *source);
+pmPhotObj *pmPhotObjAlloc(void);
 
 /// @}
 # endif /* PM_PHOT_OBJ_H */
+
Index: branches/eam_branches/stackphot.20100406/psModules/src/objects/pmSource.c
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/objects/pmSource.c	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/objects/pmSource.c	(revision 27648)
@@ -1065,4 +1065,19 @@
 }
 
+// sort by X (ascending)
+int pmSourceSortByX (const void **a, const void **b)
+{
+    pmSource *A = *(pmSource **)a;
+    pmSource *B = *(pmSource **)b;
+
+    psF32 fA = (A->peak == NULL) ? 0 : A->peak->x;
+    psF32 fB = (B->peak == NULL) ? 0 : B->peak->x;
+
+    psF32 diff = fA - fB;
+    if (diff > FLT_EPSILON) return (+1);
+    if (diff < FLT_EPSILON) return (-1);
+    return (0);
+}
+
 // sort by Seq (ascending)
 int pmSourceSortBySeq (const void **a, const void **b)
Index: branches/eam_branches/stackphot.20100406/psModules/src/objects/pmSource.h
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/objects/pmSource.h	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/objects/pmSource.h	(revision 27648)
@@ -246,4 +246,5 @@
 int  pmSourceSortBySN (const void **a, const void **b);
 int  pmSourceSortByY (const void **a, const void **b);
+int  pmSourceSortByX (const void **a, const void **b);
 int  pmSourceSortBySeq (const void **a, const void **b);
 
Index: branches/eam_branches/stackphot.20100406/psModules/src/psmodules.h
===================================================================
--- branches/eam_branches/stackphot.20100406/psModules/src/psmodules.h	(revision 27626)
+++ branches/eam_branches/stackphot.20100406/psModules/src/psmodules.h	(revision 27648)
@@ -124,4 +124,5 @@
 #include <pmSourceMasks.h>
 #include <pmSource.h>
+#include <pmPhotObj.h>
 #include <pmSourceUtils.h>
 #include <pmSourceIO.h>
