Index: trunk/psphot/src/psphotCheckStarDistribution.c
===================================================================
--- trunk/psphot/src/psphotCheckStarDistribution.c	(revision 15017)
+++ trunk/psphot/src/psphotCheckStarDistribution.c	(revision 15017)
@@ -0,0 +1,78 @@
+# include "psphotInternal.h"
+
+// 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) {
+
+    // count the number of PSFSTAR sources in each cell.  for polynomial representations, we
+    // use an image (Norder + 1) x (Norder + 1)
+    int Nx = options->psfTrendNx;
+    int Ny = options->psfTrendNy;
+    if (options->psfTrendMode != PM_TREND_MAP) {
+	Nx ++;
+	Ny ++;
+    }
+
+    // set up and image and an image binning structure to cover the field
+    psImage *nCell = psImageAlloc (Nx, Ny, PS_TYPE_S32);
+    psImageInit (nCell);
+
+    psImageBinning *binning = psImageBinningAlloc();
+    binning->nXruff = Nx;
+    binning->nYruff = Ny;
+    binning->nXfine = options->psfFieldNx;
+    binning->nYfine = options->psfFieldNy;
+
+    psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);
+    psImageBinningSetSkipByOffset (binning, options->psfFieldXo, options->psfFieldYo);
+
+    for (int i = 0; i < sources->n; i++) {
+	
+	pmSource *source = sources->data[i];
+        if (source->modelEXT == 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]);
+
+	assert (binX >= 0);
+	assert (binY >= 0);
+	assert (binX <  nCell->numCols);
+	assert (binY <  nCell->numRows);
+
+	nCell->data.S32[binY][binX] ++;
+    }
+	
+    // do any cells have too few PSFSTAR sources?
+    for (int iy = 0; iy < nCell->numRows; iy++) { 
+	for (int ix = 0; ix < nCell->numCols; ix++) { 
+	    if (nCell->data.S32[binY][binX] < NNN) {
+	    }
+	}
+    }
+
+}
+
+// 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 nNew = 0;
+
+    float Xs = psImageBinningGetFineX (binning, ix);
+    float Xe = psImageBinningGetFineX (binning, ix + 1);
+
+    float Ys = psImageBinningGetFineY (binning, iy);
+    float Ye = psImageBinningGetFineY (binning, iy + 1);
+
+    // 
+    for (int i = 0; i < sources->n; i++) {
+	
+	pmSource *source = sources->data[i];
+        if (source->modelEXT == NULL) continue;
+        if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
+
+	float x = source->modelEXT->params->data.F32[PM_PAR_XPOS];
+	float y = source->modelEXT->params->data.F32[PM_PAR_YPOS];
+
+}
Index: trunk/psphot/src/psphotChoosePSF.c
===================================================================
--- trunk/psphot/src/psphotChoosePSF.c	(revision 15000)
+++ trunk/psphot/src/psphotChoosePSF.c	(revision 15017)
@@ -62,4 +62,8 @@
 
     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);
@@ -86,30 +90,24 @@
 
     // get the list pointers for the PSF_MODEL entries
-    psList *list = NULL;
-    psMetadataItem *mdi = psMetadataLookup (recipe, "PSF_MODEL");
-    if (mdi == NULL) psAbort("missing PSF_MODEL selection");
-
-    if (mdi->type == PS_DATA_STRING) {
-        list = psListAlloc(NULL);
-        psListAdd (list, PS_LIST_HEAD, mdi);
+    psArray *modelNames = NULL;
+    psMetadataItem *item = psMetadataLookup (recipe, "PSF_MODEL");
+    if (item == NULL) psAbort("missing PSF_MODEL selection");
+
+    if (item->type == PS_DATA_STRING) {
+        modelNames = psArrayAlloc(1);
+        modelNames->data[0] = psStringCopy (item->data.V);
     } else {
-        if (mdi->type != PS_DATA_METADATA_MULTI) psAbort("missing PSF_MODEL selection");
-        list = psMemIncrRefCounter(mdi->data.list);
+        if (item->type != PS_DATA_METADATA_MULTI) psAbort("missing PSF_MODEL selection");
+	modelNames = psListToArray (item->data.list);
     }
 
     // set up an array to store the results
-    psArray *models = psArrayAlloc (list->n);
+    psArray *models = psArrayAlloc (modelNames->n);
 
     // try each model option listed in config
-    psListIterator *iter = psListIteratorAlloc (list, PS_LIST_HEAD, FALSE);
-    for (int i = 0; i < models->n; i++) {
-        psMetadataItem *item = psListGetAndIncrement (iter);
-        char *modelName = item->data.V;
+    for (int i = 0; i < modelNames->n; i++) {
+        char *modelName = modelNames->data[i];
         models->data[i] = pmPSFtryModel (stars, modelName, options, maskVal, mark);
     }
-
-    psFree (iter);
-    psFree (list);
-    psFree (stars);
 
     // select the best of the models
@@ -120,5 +118,5 @@
         pmPSFtry *try = models->data[i];
         if (try == NULL) {
-            psError(PSPHOT_ERR_PSF, false, "PSF model %d is NULL", i);
+            psTrace ("psphot", 3, "PSF model %d is NULL", i);
             continue;
         }
@@ -132,17 +130,42 @@
     // use the best model:
     if (bestN < 0) {
-        psError (PSPHOT_ERR_DATA, false, "Failed to fit any models when choosing PSF");
         psFree (models);
-        return NULL;
-    }
+	psFree (stars);
+
+	// XXX optionally give up here
+	// generate a psf model using the first selection
+	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;
+    }
+
+    psFree (modelNames);
+    psFree (stars);
 
     pmPSFtry *try = models->data[bestN];
-
-    // print/dump psf parameters
-    if (psTraceGetLevel("psphot") >= 5) {
-        for (int i = PM_PAR_SXX; i < try->psf->params->n; i++) {
-	    // XXX re-write the output or some other status info
-        }
-    }
 
     // measure and save the median value of dparams[PM_PAR_SXX],dparams[PM_PAR_SYY]
Index: trunk/psphot/src/psphotRadialPlot.c
===================================================================
--- trunk/psphot/src/psphotRadialPlot.c	(revision 15000)
+++ trunk/psphot/src/psphotRadialPlot.c	(revision 15017)
@@ -24,5 +24,5 @@
     // XXX 'showWindow = false' is broken
     if (*kapa == 0) {
-	*kapa = pmKapaOpen (true);
+	*kapa = pmKapaOpen (false);
 	KapaResize (*kapa, 500, 500);
 	unlink (filename);
