Index: /trunk/psphot/src/Makefile.am
===================================================================
--- /trunk/psphot/src/Makefile.am	(revision 15022)
+++ /trunk/psphot/src/Makefile.am	(revision 15023)
@@ -69,4 +69,5 @@
 	psphotDiagnosticPlots.c	 \
 	psphotMakeFluxScale.c	 \
+	psphotCheckStarDistribution.c \
 	psphotAddNoise.c
 
Index: /trunk/psphot/src/psphot.h
===================================================================
--- /trunk/psphot/src/psphot.h	(revision 15022)
+++ /trunk/psphot/src/psphot.h	(revision 15023)
@@ -170,3 +170,6 @@
 bool psphotMakeFluxScale (psImage *image, psMetadata *recipe, pmPSF *psf);
 
+bool psphotCheckStarDistribution (psArray *sources, psArray *stars, pmPSFOptions *options);
+int psphotSupplementStars (psArray *stars, psArray *sources, psImageBinning *binning, int ix, int iy);
+
 #endif
Index: /trunk/psphot/src/psphotCheckStarDistribution.c
===================================================================
--- /trunk/psphot/src/psphotCheckStarDistribution.c	(revision 15022)
+++ /trunk/psphot/src/psphotCheckStarDistribution.c	(revision 15023)
@@ -3,5 +3,7 @@
 // examine the x,y distribution of the psfstars and extend the selection if needed
 // desired region and coverage are specified by pmPSFOptions
-bool psphotCheckStarDistribution (psArray *sources, pmPSFOptions *options) {
+// even if stars->n is at the limit, we will add more sources to fill out the area
+
+bool psphotCheckStarDistribution (psArray *stars, psArray *sources, pmPSFOptions *options) {
 
     // count the number of PSFSTAR sources in each cell.  for polynomial representations, we
@@ -16,5 +18,5 @@
     // set up and image and an image binning structure to cover the field
     psImage *nCell = psImageAlloc (Nx, Ny, PS_TYPE_S32);
-    psImageInit (nCell);
+    psImageInit (nCell, 0);
 
     psImageBinning *binning = psImageBinningAlloc();
@@ -27,12 +29,13 @@
     psImageBinningSetSkipByOffset (binning, options->psfFieldXo, options->psfFieldYo);
 
-    for (int i = 0; i < sources->n; i++) {
+    // where are the PSF stars located?
+    for (int i = 0; i < stars->n; i++) {
 	
-	pmSource *source = sources->data[i];
-        if (source->modelEXT == NULL) continue;
+	pmSource *source = stars->data[i];
+        if (source->peak == NULL) continue;
         if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
 
-	int binX = psImageBinningGetRuffX (binning, source->modelEXT->params->data.F32[PM_PAR_XPOS]);
-	int binY = psImageBinningGetRuffX (binning, source->modelEXT->params->data.F32[PM_PAR_YPOS]);
+	int binX = psImageBinningGetRuffX (binning, source->peak->xf);
+	int binY = psImageBinningGetRuffX (binning, source->peak->yf);
 
 	assert (binX >= 0);
@@ -45,16 +48,26 @@
 	
     // do any cells have too few PSFSTAR sources?
+    // we use 3 as a minimum (slightly arbitrary...)
     for (int iy = 0; iy < nCell->numRows; iy++) { 
 	for (int ix = 0; ix < nCell->numCols; ix++) { 
-	    if (nCell->data.S32[binY][binX] < NNN) {
+	    if (nCell->data.S32[iy][ix] < 3) {
+		int nNew = psphotSupplementStars (stars, sources, binning, ix, iy);
+		if (nNew) {
+		    psLogMsg ("pmObjects", 3, "added %d fainter PSF candidates to %d,%d\n", nNew, ix, iy);
+		} else {
+		    psLogMsg ("pmObjects", 3, "tried to add to %d,%d, but no more sources are available\n", ix, iy);		    
+		}
 	    }
 	}
     }
 
+    psFree (nCell);
+    psFree (binning);
+    return true;
 }
 
 // select more possible PSF stars in the specified cell
 // sources should be sorted by SN before calling this function
-bool psphotSupplementStars (psArray *sources, psImageBinning *binning, int ix, int iy) {
+int psphotSupplementStars (psArray *stars, psArray *sources, psImageBinning *binning, int ix, int iy) {
 
     int nNew = 0;
@@ -66,13 +79,26 @@
     float Ye = psImageBinningGetFineY (binning, iy + 1);
 
-    // 
     for (int i = 0; i < sources->n; i++) {
-	
+
+	// add sources which are marked as stars, in S/N order until...
 	pmSource *source = sources->data[i];
-        if (source->modelEXT == NULL) continue;
-        if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
+        if (source->peak == NULL) continue;
+        if (source->moments == NULL) continue;
+        if (source->mode & PM_SOURCE_MODE_PSFSTAR) continue;
+        if (source->type != PM_SOURCE_TYPE_STAR) continue;
 
-	float x = source->modelEXT->params->data.F32[PM_PAR_XPOS];
-	float y = source->modelEXT->params->data.F32[PM_PAR_YPOS];
+	float x = source->peak->xf;
+	float y = source->peak->yf;
 
+	if (x < Xs) continue;
+	if (y < Ys) continue;
+	if (x > Xe) continue;
+	if (y > Ye) continue;
+
+	source->mode |= PM_SOURCE_MODE_PSFSTAR;
+	psArrayAdd (stars, 200, source);
+
+	nNew ++;
+    }
+    return nNew;
 }
Index: /trunk/psphot/src/psphotChoosePSF.c
===================================================================
--- /trunk/psphot/src/psphotChoosePSF.c	(revision 15022)
+++ /trunk/psphot/src/psphotChoosePSF.c	(revision 15023)
@@ -62,8 +62,4 @@
 
     pmSourceFitModelInit (15, 0.01, PS_SQR(SKY_SIG), options->poissonErrorsPhotLMM);
-
-    // check that the identified psf stars sufficiently cover the region; if not, extend the
-    // limits somewhat
-    // psphotCheckStarDistribution (sources, options);
 
     psArray *stars = psArrayAllocEmpty (sources->n);
@@ -81,11 +77,9 @@
         }
     }
+    // check that the identified psf stars sufficiently cover the region; if not, extend the
+    // limits somewhat
+    psphotCheckStarDistribution (stars, sources, options);
+
     psLogMsg ("psphot.pspsf", PS_LOG_DETAIL, "selected candidate %ld PSF objects\n", stars->n);
-
-    if (stars->n == 0) {
-        psLogMsg ("psphot.choosePSF", PS_LOG_WARN, "Failed to find any PSF candidates");
-        psFree (stars);
-        return NULL;
-    }
 
     // get the list pointers for the PSF_MODEL entries
@@ -100,4 +94,36 @@
         if (item->type != PS_DATA_METADATA_MULTI) psAbort("missing PSF_MODEL selection");
 	modelNames = psListToArray (item->data.list);
+    }
+
+    // generate a psf model using the first selection
+    if (stars->n == 0) {
+	// XXX optionally give up here
+	psError(PSPHOT_ERR_PSF, false, "Failed to fit any models when choosing PSF");
+	psErrorStackPrint (stderr, "Using guess PSF model");
+	psErrorClear ();
+	
+	// unset the PSFSTAR flags (none are used):
+	for (int i = 0; i < sources->n; i++) {
+	    pmSource *source = sources->data[i];
+	    source->mode &= ~PM_SOURCE_MODE_PSFSTAR;
+	}
+
+	// XXX set sxx, etc from FWHM in recipe
+	pmPSF *psf = pmPSFBuildSimple (modelNames->data[0], 1.0, 1.0, 0.0, 1.0);
+	psf->fieldNx = readout->image->numCols;
+	psf->fieldNy = readout->image->numRows;
+	psFree (modelNames);
+
+	bool status = true;
+	status &= psphotMakeFluxScale (readout->image, recipe, psf);
+	status &= psphotPSFstats (readout, recipe, psf);
+	if (!status) {
+	    psError(PSPHOT_ERR_PSF, false, "Failed to fit any models when choosing PSF");
+	    psFree (psf);
+	    return NULL;
+	}
+
+	// XXX set DSX_MEAN, etc?
+        return psf;
     }
 
