Index: /trunk/psastro/src/psastroExtractAnalysis.c
===================================================================
--- /trunk/psastro/src/psastroExtractAnalysis.c	(revision 23591)
+++ /trunk/psastro/src/psastroExtractAnalysis.c	(revision 23592)
@@ -51,6 +51,8 @@
     psFree(refs);
 
+    // convert star positions to ghost positions and add to the readout->analysis data
+    psastroExtractGhosts (config);
+
     psastroExtractStars (config);
-    psastroExtractGhosts (config);
     return true;
 }
Index: /trunk/psastro/src/psastroExtractGhosts.c
===================================================================
--- /trunk/psastro/src/psastroExtractGhosts.c	(revision 23591)
+++ /trunk/psastro/src/psastroExtractGhosts.c	(revision 23592)
@@ -29,7 +29,6 @@
     pmReadout *readout = NULL;
     float zeropt, exptime;
-    char extname[81];
 
-    psLogMsg ("psastro", PS_LOG_INFO, "extracting bright-star subrasters");
+    psLogMsg ("psastro", PS_LOG_INFO, "determine ghost positions");
 
     // select the current recipe
@@ -53,15 +52,4 @@
     pmFPA *fpa = astrom->fpa;
 
-    // select the input data sources
-    pmFPAfile *input = psMetadataLookupPtr (NULL, config->files, "PSASTRO.EXTRACT.INPUT");
-    if (!input) {
-        psError(PSASTRO_ERR_CONFIG, true, "Can't find input data");
-        return false;
-    }
-
-    // only load data from INPUT
-    pmFPAfileActivate(config->files, false, NULL);
-    pmFPAfileActivate(config->files, true, "PSASTRO.EXTRACT.INPUT");
-
     // really error-out here?  or just skip?
     if (!psastroZeroPointFromRecipe (&zeropt, &exptime, fpa, recipe)) {
@@ -75,37 +63,5 @@
     EXTRACT_MAX_MAG += MagOffset;
 
-    int nExt = 0;
-
-    // open the output file handle: we are just saving a series of extensions to this file
-    char *fileroot = psMetadataLookupStr (&status, config->arguments, "OUTPUT");
-    if (!fileroot) {
-	psLogMsg ("psastro", PS_LOG_INFO, "output filename not supplied");
-	return false;
-    }
-    char *filename = NULL;
-    psStringAppend (&filename, "%s.gh.fits", fileroot);
-
-    psFits *outStars = psFitsOpen (filename, "w");
-    if (!outStars) {
-	psError(PS_ERR_IO, false, "error opening file %s\n", filename);
-	return false;
-    }
-
     pmFPAview *view = pmFPAviewAlloc (0);
-
-    // generate a (very) basic header:
-    psMetadata *phu = psMetadataAlloc ();
-    // select the filter; default to fixed photcode and mag limit otherwise
-    char *filter = psMetadataLookupStr (&status, fpa->concepts, "FPA.FILTERID");
-    if (!status) ESCAPE("missing FPA.FILTER in concepts");
-
-    psMetadataAddStr (phu, PS_LIST_TAIL, "FILTER",  0, "filter", filter);
-    psMetadataAddF32 (phu, PS_LIST_TAIL, "EXPTIME", 0, "exptime", exptime);
-    psMetadataAddF32 (phu, PS_LIST_TAIL, "ZEROPT",  0, "zeropt", zeropt);
-    psFitsWriteBlank (outStars, phu, NULL);
-    psFree (phu);
-
-    // open/load files as needed
-    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE("failed on FPA BEFORE");
 
     // this loop selects the matched stars for all chips
@@ -114,6 +70,4 @@
         if (!chip->process || !chip->file_exists) { continue; }
         if (!chip->fromFPA) { continue; }
-
-        if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE("failed on Chip BEFORE");
 
         while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
@@ -150,33 +104,27 @@
 		    if (!ghostReadout) continue;
 
-		    // XXX box size needs to be larger...
-		    psImage *subraster = psastroExtractStar (ghostReadout->image, xChip, yChip, 200.0, 200.0);
-		    if (!subraster) continue;
+		    psArray *ghosts = psMetadataLookupPtr (&status, ghostReadout->analysis, "PSASTRO.GHOSTS");
+		    if (ghosts == NULL) { 
+			ghosts = psArrayAllocEmpty (100);
+			psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSASTRO.GHOSTS", PS_DATA_ARRAY, "astrometry matches", ghosts);
+			psFree (ghosts);
+		    }
+
+		    pmAstromObj *ghost = pmAstromObjAlloc ();
+		    ghost->FP->x   = xFPA;
+		    ghost->FP->y   = yFPA;
+		    ghost->chip->x = xChip;
+		    ghost->chip->y = yChip;
+		    ghost->TP->x   = ref->FP->x; // XXX this is a bit of sleazy over-loading
+		    ghost->TP->y   = ref->FP->y;
+		    ghost->Mag     = ref->Mag;
 		    
-                    // generate a (very) basic header:
-                    psMetadata *header = psMetadataAlloc ();
-                    psMetadataAddF32 (header, PS_LIST_TAIL, "CHIP_X",  0, "chip coordinate",        ref->chip->x);
-                    psMetadataAddF32 (header, PS_LIST_TAIL, "CHIP_Y",  0, "chip coordinate",        ref->chip->y);
-                    psMetadataAddF32 (header, PS_LIST_TAIL, "FPA_X",   0, "focal-plane coordinate", ref->FP->x);
-                    psMetadataAddF32 (header, PS_LIST_TAIL, "FPA_Y",   0, "focal-plane coordinate", ref->FP->y);
-                    psMetadataAddF32 (header, PS_LIST_TAIL, "MAG",     0, "magnitude",              ref->Mag);
+		    psArrayAdd (ghosts, 100, ghost);
+		    psFree (ghost);
+                }
+            }
+        }
+    }
 
-		    snprintf (extname, 80, "extname.%05d", nExt);
-		    psFitsWriteImage (outStars, header, subraster, 0, extname);
-		    nExt ++;
-		    
-		    psFree (header);
-		    psFree (subraster);
-                }
-                if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE("failed on Readout AFTER");;
-            }
-            if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE("failed on Cell AFTER");;
-        }
-        if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE("failed on Chip AFTER");;
-    }
-    if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE("failed on FPA AFTER");;
-
-    psFitsClose (outStars);
-    psFree (filename);
     psFree (view);
     return true;
Index: /trunk/psastro/src/psastroExtractStars.c
===================================================================
--- /trunk/psastro/src/psastroExtractStars.c	(revision 23591)
+++ /trunk/psastro/src/psastroExtractStars.c	(revision 23592)
@@ -83,7 +83,7 @@
 	return false;
     }
+
     char *filename = NULL;
     psStringAppend (&filename, "%s.st.fits", fileroot);
-
     psFits *outStars = psFitsOpen (filename, "w");
     if (!outStars) {
@@ -91,4 +91,14 @@
 	return false;
     }
+    psFree (filename);
+
+    filename = NULL;
+    psStringAppend (&filename, "%s.gh.fits", fileroot);
+    psFits *outGhosts = psFitsOpen (filename, "w");
+    if (!outGhosts) {
+	psError(PS_ERR_IO, false, "error opening file %s\n", filename);
+	return false;
+    }
+    psFree (filename);
 
     pmFPAview *view = pmFPAviewAlloc (0);
@@ -103,5 +113,7 @@
     psMetadataAddF32 (phu, PS_LIST_TAIL, "EXPTIME", 0, "exptime", exptime);
     psMetadataAddF32 (phu, PS_LIST_TAIL, "ZEROPT",  0, "zeropt", zeropt);
+
     psFitsWriteBlank (outStars, phu, NULL);
+    psFitsWriteBlank (outGhosts, phu, NULL);
     psFree (phu);
 
@@ -145,4 +157,34 @@
                     psMetadataAddF32 (header, PS_LIST_TAIL, "FPA_Y",   0, "focal-plane coordinate", ref->FP->y);
                     psMetadataAddF32 (header, PS_LIST_TAIL, "MAG",     0, "magnitude",              ref->Mag);
+
+		    snprintf (extname, 80, "extname.%05d", nExt);
+		    psFitsWriteImage (outStars, header, subraster, 0, extname);
+		    nExt ++;
+		    
+		    psFree (header);
+		    psFree (subraster);
+                }
+
+                // select the raw objects for this readout (loaded in psastroExtract.c)
+                psArray *ghosts = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.GHOSTS");
+                if (ghosts == NULL) { continue; }
+
+                // identify the bright stars of interest
+                for (int i = 0; i < ghosts->n; i++) {
+                    pmAstromObj *ghost = ghosts->data[i];
+
+		    pmReadout *inReadout = pmFPAviewThisReadout (view, input->fpa);
+		    psImage *subraster = psastroExtractStar (inReadout->image, ghost->chip->x, ghost->chip->y, 200.0, 200.0);
+		    if (!subraster) continue;
+		    
+                    // generate a (very) basic header:
+                    psMetadata *header = psMetadataAlloc ();
+                    psMetadataAddF32 (header, PS_LIST_TAIL, "CHIP_X",  0, "chip coordinate",        ghost->chip->x);
+                    psMetadataAddF32 (header, PS_LIST_TAIL, "CHIP_Y",  0, "chip coordinate",        ghost->chip->y);
+                    psMetadataAddF32 (header, PS_LIST_TAIL, "FPA_X",   0, "focal-plane coordinate", ghost->FP->x);
+                    psMetadataAddF32 (header, PS_LIST_TAIL, "FPA_Y",   0, "focal-plane coordinate", ghost->FP->y);
+                    psMetadataAddF32 (header, PS_LIST_TAIL, "FPA_X0",  0, "star focal-plane coordinate", ghost->TP->x); // note : over-loaded value 
+                    psMetadataAddF32 (header, PS_LIST_TAIL, "FPA_Y0",  0, "star focal-plane coordinate", ghost->TP->y); // note : over-loaded value 
+                    psMetadataAddF32 (header, PS_LIST_TAIL, "MAG",     0, "magnitude",              ghost->Mag);
 
 		    snprintf (extname, 80, "extname.%05d", nExt);
