Index: /trunk/psphot/src/Makefile.am
===================================================================
--- /trunk/psphot/src/Makefile.am	(revision 13224)
+++ /trunk/psphot/src/Makefile.am	(revision 13225)
@@ -50,4 +50,5 @@
 	psphotSummaryPlots.c     \
 	psphotMergeSources.c	 \
+	psphotLoadPSF.c	 \
 	psphotReadoutCleanup.c	 \
 	psphotSourcePlots.c	 \
Index: /trunk/psphot/src/psphot.h
===================================================================
--- /trunk/psphot/src/psphot.h	(revision 13224)
+++ /trunk/psphot/src/psphot.h	(revision 13225)
@@ -98,4 +98,5 @@
 bool 		psphotMergeSources (psArray *oldSources, psArray *newSources);
 bool 		psphotLoadExtSources (pmConfig *config, pmFPAview *view, psArray *sources);
+pmPSF 	       *psphotLoadPSF (pmConfig *config, pmFPAview *view, psMetadata *recipe);
 bool 		psphotSetHeaderNstars (psMetadata *recipe, psArray *sources);
 bool 		psphotAddNoise (pmReadout *readout, psArray *sources, psMetadata *recipe, bool add);
Index: /trunk/psphot/src/psphotChoosePSF.c
===================================================================
--- /trunk/psphot/src/psphotChoosePSF.c	(revision 13224)
+++ /trunk/psphot/src/psphotChoosePSF.c	(revision 13225)
@@ -12,11 +12,4 @@
     psTimerStart ("psphot");
 
-    // check if a PSF model is supplied by the user
-    psf = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.PSF");
-    if (psf != NULL) {
-        if (!psphotPSFstats (readout, recipe, psf)) psAbort("cannot measure PSF shape terms");
-	return psf;
-    }
-
     // examine PSF sources in S/N order (brightest first)
     sources = psArraySort (sources, pmSourceSortBySN);
@@ -24,49 +17,36 @@
     // array to store candidate PSF stars
     int NSTARS = psMetadataLookupS32 (&status, recipe, "PSF_MAX_NSTARS");
-    if (!status) {
-        NSTARS = PS_MIN (sources->n, 200);
-        psWarning("PSF_MAX_NSTARS is not set in the recipe --- defaulting to %d\n", NSTARS);
-    }
+    PS_ASSERT (status, NULL);
 
     float PSF_MIN_DS = psMetadataLookupF32 (&status, recipe, "PSF_MIN_DS");
-    if (!status) {
-	PSF_MIN_DS = 0.01;
-        psWarning("PSF_MIN_DS is not set --- defaulting to %f\n", PSF_MIN_DS);
-    }
+    PS_ASSERT (status, NULL);
 
     // supply the measured sky variance for optional constant errors (non-poissonian)
     float SKY_SIG = psMetadataLookupF32 (&status, recipe, "SKY_SIG");
-    if (!status) {
-	SKY_SIG = 1.0;
-        psWarning("SKY_SIG is not set --- defaulting to %f\n", SKY_SIG);
-    }
+    PS_ASSERT (status, NULL);
+
     // use poissonian errors or local-sky errors
     bool POISSON_ERRORS = psMetadataLookupBool (&status, recipe, "POISSON_ERRORS");
-    if (!status) {
-        POISSON_ERRORS = true;
-        psWarning("POISSON_ERRORS is not set in the recipe --- defaulting to true.\n");
-    }
-    pmSourceFitModelInit (15, 0.01, PS_SQR(SKY_SIG), POISSON_ERRORS);
+    PS_ASSERT (status, NULL);
 
     // use poissonian errors or local-sky errors
     bool PSF_PARAM_WEIGHTS = psMetadataLookupBool (&status, recipe, "PSF_PARAM_WEIGHTS");
-    if (!status) {
-        PSF_PARAM_WEIGHTS = false;
-        psWarning("PSF_PARAM_WEIGHTS is not set in the recipe --- defaulting to false.\n");
-    }
+    PS_ASSERT (status, NULL);
 
     // how to model the PSF variations across the field
-    // XXX make a default value?  or not?
     psMetadata *md = psMetadataLookupMetadata (&status, recipe, "PSF.TREND.MASK");
-    psPolynomial2D *psfTrendMask;
-    if (!status || !md) {
-        psWarning("PSF.TREND.MASK is not set in the recipe --- defaulting to use zeroth order.\n");
-        psfTrendMask = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 0, 0);
-    } else {
-        psfTrendMask = psPolynomial2DfromMetadata (md);
-        if (!psfTrendMask) {
-            psError(PSPHOT_ERR_PSF, true, "Unable to construct polynomial from PSF.TREND.MASK in the recipe");
-            return NULL;
-        }
+    PS_ASSERT (status, NULL);
+
+    // get the fixed PSF fit radius
+    // XXX check that PSF_FIT_RADIUS < SKY_OUTER_RADIUS
+    float RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_FIT_RADIUS");
+    PS_ASSERT (status, NULL);
+
+    pmSourceFitModelInit (15, 0.01, PS_SQR(SKY_SIG), POISSON_ERRORS);
+
+    psPolynomial2D *psfTrendMask = psPolynomial2DfromMetadata (md);
+    if (!psfTrendMask) {
+	psError(PSPHOT_ERR_PSF, true, "Unable to construct polynomial from PSF.TREND.MASK in the recipe");
+	return NULL;
     }
 
@@ -90,12 +70,4 @@
         psError(PSPHOT_ERR_PSF, true, "Failed to find any PSF candidates");
         return NULL;
-    }
-
-    // get the fixed PSF fit radius
-    // XXX EAM : check that PSF_FIT_RADIUS < SKY_OUTER_RADIUS
-    float RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_FIT_RADIUS");
-    if (!status) {
-        RADIUS = 20.0;
-        psWarning("PSF_FIT_RADIUS is not set in the recipe --- defaulting to %g\n", RADIUS);
     }
 
Index: /trunk/psphot/src/psphotDefineFiles.c
===================================================================
--- /trunk/psphot/src/psphotDefineFiles.c	(revision 13224)
+++ /trunk/psphot/src/psphotDefineFiles.c	(revision 13225)
@@ -87,4 +87,20 @@
     }
 
+    if (psMetadataLookupPtr(NULL, config->arguments, "SRC")) { 
+	pmFPAfileDefineFromArgs (&status, config, "PSPHOT.INPUT.CMF", "SRC");
+	if (!status) {
+	    psError(PSPHOT_ERR_CONFIG, false, "Failed to find/build PSPHOT.INPUT.CMF");
+	    return status;
+	}
+    }
+
+    if (psMetadataLookupPtr(NULL, config->arguments, "PSF")) { 
+	pmFPAfileDefineFromArgs (&status, config, "PSPHOT.PSF.LOAD", "PSF");
+	if (!status) {
+	    psError(PSPHOT_ERR_CONFIG, false, "Failed to find/build PSPHOT.SRC");
+	    return status;
+	}
+    }
+
     // XXX add in example PSF image thumbnails
     // pmFPAfileConstruct (config->files, format, config->camera, "PSPHOT.PSF_SAMPLE");
@@ -98,11 +114,4 @@
     // before it is added back into the code.
 # if (0)    
-    if (psMetadataLookupPtr(NULL, config->arguments, "SRC")) { 
-	pmFPAfileDefineFromArgs (&status, config, "PSPHOT.SRC", "SRC");
-	if (!status) {
-	    psError(PSPHOT_ERR_CONFIG, false, "Failed to find/build PSPHOT.SRC");
-	    return status;
-	}
-    }
     // optionally load the PSF Model and/or fixed stars
     // XXX add this back in later
Index: /trunk/psphot/src/psphotLoadPSF.c
===================================================================
--- /trunk/psphot/src/psphotLoadPSF.c	(revision 13225)
+++ /trunk/psphot/src/psphotLoadPSF.c	(revision 13225)
@@ -0,0 +1,19 @@
+# include "psphotInternal.h"
+
+// load an externally supplied psf model
+pmPSF *psphotLoadPSF (pmConfig *config, pmFPAview *view, psMetadata *recipe) {
+
+    // find the currently selected readout
+    pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.LOAD.PSF");
+    if (!readout) return NULL;
+
+    // check if a PSF model is supplied by the user
+    pmPSF *psf = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.PSF");
+    if (psf == NULL) {
+	psLogMsg ("psphot", 3, "no psf supplied for this readout");
+	return NULL;
+    }
+
+    if (!psphotPSFstats (readout, recipe, psf)) psAbort("cannot measure PSF shape terms");
+    return psf;
+}
Index: /trunk/psphot/src/psphotMergeSources.c
===================================================================
--- /trunk/psphot/src/psphotMergeSources.c	(revision 13224)
+++ /trunk/psphot/src/psphotMergeSources.c	(revision 13225)
@@ -16,5 +16,5 @@
 
     // find the currently selected readout
-    pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.SRC");
+    pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CMF");
     if (!readout) {
 	psLogMsg ("psphot", 3, "no external sources supplied");
Index: /trunk/psphot/src/psphotReadout.c
===================================================================
--- /trunk/psphot/src/psphotReadout.c	(revision 13224)
+++ /trunk/psphot/src/psphotReadout.c	(revision 13225)
@@ -104,9 +104,13 @@
     }
 
-    // use bright stellar objects to measure PSF
-    pmPSF *psf = psphotChoosePSF (readout, sources, recipe);
-    if (psf == NULL) {
-	psLogMsg ("psphot", 3, "failure to construct a psf model");
-	return psphotReadoutCleanup (config, readout, recipe, psf, sources);
+    // load the psf model, if suppled
+    pmPSF *psf = psphotLoadPSF (config, view, recipe);
+    if (!psf) {
+	// use bright stellar objects to measure PSF
+	psf = psphotChoosePSF (readout, sources, recipe);
+	if (psf == NULL) {
+	    psLogMsg ("psphot", 3, "failure to construct a psf model");
+	    return psphotReadoutCleanup (config, readout, recipe, psf, sources);
+	}
     }
     if (!strcasecmp (breakPt, "PSFMODEL")) {
