Index: /trunk/psModules/src/objects/Makefile.am
===================================================================
--- /trunk/psModules/src/objects/Makefile.am	(revision 23989)
+++ /trunk/psModules/src/objects/Makefile.am	(revision 23990)
@@ -38,4 +38,5 @@
 	pmSourceIO_PS1_CAL_0.c \
 	pmSourceIO_CMF_PS1_V1.c \
+	pmSourceIO_MatchedRefs.c \
 	pmSourcePlots.c \
 	pmSourcePlotPSFModel.c \
Index: /trunk/psModules/src/objects/pmSourceIO.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO.c	(revision 23989)
+++ /trunk/psModules/src/objects/pmSourceIO.c	(revision 23990)
@@ -562,6 +562,8 @@
 
     // not needed if only one chip
-    if (file->fpa->chips->n == 1) return true;
-
+    if (file->fpa->chips->n == 1) {
+	pmSourceWriteMatchedRefs (file->fits, file->fpa, config);
+	return true;
+    }
 
     // find the FPA phu
@@ -667,4 +669,5 @@
     psFree (outhead);
 
+    pmSourceWriteMatchedRefs (file->fits, file->fpa, config);
     return true;
 }
@@ -1053,2 +1056,3 @@
 }
 
+    
Index: /trunk/psModules/src/objects/pmSourceIO.h
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO.h	(revision 23989)
+++ /trunk/psModules/src/objects/pmSourceIO.h	(revision 23990)
@@ -75,4 +75,6 @@
 bool pmSourceLocalAstrometry (psSphere *ptSky, float *posAngle, float *pltScale, pmChip *chip, float xPos, float yPos);
 
+bool pmSourceWriteMatchedRefs (psFits *fits, pmFPA *fpa, pmConfig *config);
+
 /// @}
 # endif /* PM_SOURCE_IO_H */
Index: /trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c	(revision 23990)
+++ /trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c	(revision 23990)
@@ -0,0 +1,135 @@
+/** @file  pmSourceIO_MatchedRefs.c
+ *
+ *  @author EAM, IfA
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-18 02:44:19 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <pslib.h>
+
+#include "pmConfig.h"
+#include "pmDetrendDB.h"
+
+#include "pmHDU.h"
+#include "pmFPA.h"
+#include "pmFPALevel.h"
+#include "pmFPAview.h"
+#include "pmFPAfile.h"
+
+#include "pmSpan.h"
+#include "pmFootprint.h"
+#include "pmPeaks.h"
+#include "pmMoments.h"
+#include "pmGrowthCurve.h"
+#include "pmResiduals.h"
+#include "pmTrend2D.h"
+#include "pmPSF.h"
+#include "pmModel.h"
+#include "pmSource.h"
+#include "pmModelClass.h"
+#include "pmSourceIO.h"
+#include "pmAstrometryObjects.h"
+#include "pmAstrometryWCS.h"
+
+bool pmSourceWriteMatchedRefs (psFits *fits, pmFPA *fpa, pmConfig *config) {
+
+    bool status = true;
+    pmChip *chip = NULL;
+    pmCell *cell = NULL;
+    pmReadout *readout = NULL;
+    pmFPAview *view = pmFPAviewAlloc (0);
+
+    // first, check if there are any matches to be written
+
+    // determine the output table format
+    // XXX move this elsewhere? (psastro recipe? filerules?)
+    psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, "PSASTRO");
+    if (!status) {
+	psError(PS_ERR_UNKNOWN, true, "missing recipe PSASTRO in config data");
+	return false;
+    }
+
+    bool REFS_OUTPUT = psMetadataLookupBool(&status, recipe, "PSASTRO.SAVE.REFMATCH");
+    if (!REFS_OUTPUT) return true;
+
+    psArray *table = psArrayAllocEmpty (0x1000);
+
+    // this loop selects the matched stars for all chips
+    while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
+        psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process || !chip->file_exists) continue;
+	
+	char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
+
+	while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
+            psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+            if (!cell->process || !cell->file_exists) continue;
+
+	    // process each of the readouts
+	    // XXX there can only be one readout per chip, right?
+	    while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
+		if (! readout->data_exists) continue;
+
+		// select the raw objects for this readout
+		psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS");
+		if (rawstars == NULL) continue;
+
+		// select the raw objects for this readout
+		psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS");
+		if (refstars == NULL) continue;
+		psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n);
+
+		psArray *matches = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.MATCH");
+		if (matches == NULL) continue;
+
+		for (int i = 0; i < matches->n; i++) {
+		    pmAstromMatch *match = matches->data[i];
+
+		    pmAstromObj *raw = rawstars->data[match->raw];
+		    pmAstromObj *ref = refstars->data[match->ref];
+
+		    psMetadata *row = psMetadataAlloc ();
+		    psMetadataAdd (row, PS_LIST_TAIL, "RA",       PS_DATA_F64, "right ascension (deg, J2000)", PM_DEG_RAD*ref->sky->r);
+		    psMetadataAdd (row, PS_LIST_TAIL, "DEC",      PS_DATA_F64, "declination (deg, J2000)",     PM_DEG_RAD*ref->sky->d);
+		    psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP",   PS_DATA_F32, "x coord on chip", 	       raw->chip->x);
+		    psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP",   PS_DATA_F32, "y coord on chip", 	       raw->chip->y);   
+		    psMetadataAdd (row, PS_LIST_TAIL, "X_FPA",    PS_DATA_F32, "x coord on focal plane",       raw->FP->x);
+		    psMetadataAdd (row, PS_LIST_TAIL, "Y_FPA",    PS_DATA_F32, "y coord on focal plane",       raw->FP->y);
+		    psMetadataAdd (row, PS_LIST_TAIL, "MAG_INST", PS_DATA_F32, "instrumental magnitude",       raw->Mag);
+		    psMetadataAdd (row, PS_LIST_TAIL, "MAG_REF",  PS_DATA_F32, "reference star magnitude",     ref->Mag);
+		    psMetadataAdd (row, PS_LIST_TAIL, "CHIP_ID",  PS_DATA_STRING, "chip identifier",           chipName);
+		    // XXX need to add the reference color, but this needs getstar / dvo.photcodes for the reference to be refined.
+
+		    psArrayAdd (table, 100, row);
+		    psFree (row);
+		}
+	    }
+	}
+    }
+    psFree (view);
+
+    if (table->n == 0) {
+	psFree(table);
+	return true;
+    }
+
+    if (!psFitsWriteTable(fits, NULL, table, "MATCHED_REFS")) {
+        psError(PS_ERR_IO, false, "writing MATCHED_REFS\n");
+        psFree(table);
+        return false;
+    }
+
+    psFree(table);
+    return true;
+}
