Index: /branches/eam_branch_20070817/ppSim/src/Makefile.am
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/Makefile.am	(revision 14613)
+++ /branches/eam_branch_20070817/ppSim/src/Makefile.am	(revision 14614)
@@ -19,4 +19,5 @@
 	ppSimBounds.c           \
 	ppSimStars.c            \
+	ppSimSetPSF.c           \
 	ppSimUtils.c            \
 	ppSimLoop.c
Index: /branches/eam_branch_20070817/ppSim/src/ppSim.c
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/ppSim.c	(revision 14613)
+++ /branches/eam_branch_20070817/ppSim/src/ppSim.c	(revision 14614)
@@ -4,4 +4,6 @@
 {
     psLibInit(NULL);
+    if (!pmModelClassInit ()) abort();
+
     pmConfig *config = pmConfigRead(&argc, argv, NULL); // Configuration
     if (!config) {
@@ -18,9 +20,8 @@
     }
 
-    psExit loopError;
-    if ((loopError = ppSimLoop(config))) {
+    if (!ppSimLoop(config)) {
         psErrorStackPrint(stderr, "Unable to generate data.");
         psFree(config);
-        exit(loopError);
+        exit(PS_EXIT_SYS_ERROR);
     }
 
Index: /branches/eam_branch_20070817/ppSim/src/ppSim.h
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/ppSim.h	(revision 14613)
+++ /branches/eam_branch_20070817/ppSim/src/ppSim.h	(revision 14614)
@@ -72,5 +72,5 @@
 
 /// Loop over the output file, generating simulated data
-psExit ppSimLoop(pmConfig *config ///< Configuration
+bool ppSimLoop(pmConfig *config ///< Configuration
 		 );
 
@@ -115,3 +115,5 @@
     );
 
+bool ppSimSetPSF (pmChip *chip, pmConfig *config);
+
 #endif
Index: /branches/eam_branch_20070817/ppSim/src/ppSimArguments.c
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/ppSimArguments.c	(revision 14613)
+++ /branches/eam_branch_20070817/ppSim/src/ppSimArguments.c	(revision 14614)
@@ -66,4 +66,5 @@
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-starsmag", 0, "Brightest magnitude for fake stars", NAN);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-starsdensity", 0, "Density of fake stars at magnitude", NAN);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-psfclass", 0, "Type of PSF model", NULL);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-bin", 0, "Binning in x and y", 1);
 
@@ -194,4 +195,8 @@
         psMetadataAddF32(config->arguments, PS_LIST_TAIL, "PA", 0, "Boresight position angle (radians)",
                          pa * M_PI / 180.0);
+
+
+	const char *psfClass = psMetadataLookupStr(NULL, arguments, "-psfclass"); // Filter name
+	psMetadataAddStr(config->arguments, PS_LIST_TAIL, "PSF.MODEL", 0, "PSF model class", psfClass);
     }
 
Index: /branches/eam_branch_20070817/ppSim/src/ppSimCreate.c
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/ppSimCreate.c	(revision 14613)
+++ /branches/eam_branch_20070817/ppSim/src/ppSimCreate.c	(revision 14614)
@@ -1,3 +1,9 @@
 # include "ppSim.h"
+
+// XXX this function forces us to define the camera (on the command line) and format (via the
+// PPSIM.OUTPUT entry).  In this case, we need to set config->format,formatName based on these
+// values.  This will be a problem when we want to load an input image (in order to add fake
+// stars).  We will need to add some logic in ppSimArguments to distinguish the cases of 1)
+// input image and 2) specified camera
 
 pmFPAfile *ppSimCreate(pmConfig *config)
@@ -25,7 +31,12 @@
     file->save = true;
 
+    config->format = psMemIncrRefCounter (file->format);
+    config->formatName = psStringCopy (file->formatName);
+
     // have we supplied a psf model?
     if (psMetadataLookupPtr(NULL, config->arguments, "PSPHOT.PSF")) {
 	bool status = false;
+
+	// tie the psf file to the chipMosaic 
         pmFPAfileBindFromArgs(&status, file, config, "PSPHOT.PSF.LOAD", "PSPHOT.PSF");
         if (!status) {
Index: /branches/eam_branch_20070817/ppSim/src/ppSimInsertSources.c
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/ppSimInsertSources.c	(revision 14613)
+++ /branches/eam_branch_20070817/ppSim/src/ppSimInsertSources.c	(revision 14614)
@@ -3,13 +3,15 @@
 bool ppSimInsertSources (pmReadout *readout, psImage *expCorr, psArray *stars, pmConfig *config) {
 
+    bool mdok;
 
     assert (stars);
+    assert (readout);
     
     pmCell *cell = readout->parent;
     pmChip *chip = cell->parent;
 
-    // XXX we probably need this to get the size right
-# if (0)
-    bool mdok;
+    // XXX this is an estimate of the sky noise based on the inputs to the image simulation.
+    // XXX update this to allow the estimate based on the measured sky background
+    // XXX this is missing the gain.
     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSIM_RECIPE); // Recipe
 
@@ -29,5 +31,4 @@
     // Rough noise estimate, appropriate for entire cell (use for source radius?)
     float roughNoise = sqrtf(PS_SQR(readnoise) + (darkRate + skyRate) * expTime);
-# endif
 
     int x0Chip = psMetadataLookupS32(NULL, chip->concepts, "CHIP.X0");
@@ -43,5 +44,6 @@
     int binning = psMetadataLookupS32(NULL, config->arguments, "BINNING"); // Binning in x and y
 
-    pmPSF *psf = psMetadataLookupPtr (NULL, chip->analysis, "PSF");
+    pmPSF *psf = psMetadataLookupPtr (&mdok, chip->analysis, "PSPHOT.PSF");
+    assert (psf);
 
     int dX = PM_CELL_TO_CHIP (0.0, x0Cell, xParityCell, binning);
@@ -74,9 +76,14 @@
 	pmModelSetFlux (model, star->flux);
 
+	// XXX let the flux limit be a user-defined number of sky sigmas (not just 1.0)
+	float radius = model->modelRadius (model->params, roughNoise);
+	radius = PS_MAX (radius, 1.0);
+
 	// construct a source, with model flux pixels set, based on the model
-	pmSource *source = pmSourceFromModel (model, readout, PM_SOURCE_TYPE_STAR);
+	pmSource *source = pmSourceFromModel (model, readout, radius, PM_SOURCE_TYPE_STAR);
 
 	// XXX add the sources to a source array
 
+	// insert the source flux in the image
 	pmSourceAddWithOffset (source, PM_MODEL_OP_FULL, 0xff, dX, dY);
     }
Index: /branches/eam_branch_20070817/ppSim/src/ppSimLoop.c
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/ppSimLoop.c	(revision 14613)
+++ /branches/eam_branch_20070817/ppSim/src/ppSimLoop.c	(revision 14614)
@@ -1,5 +1,5 @@
 #include "ppSim.h"
 
-psExit ppSimLoop(pmConfig *config)
+bool ppSimLoop(pmConfig *config)
 {
     PS_ASSERT_PTR_NON_NULL(config, PS_EXIT_PROG_ERROR);
@@ -48,7 +48,10 @@
 	}
 
-	// XXX check for a supplied PSF, otherwise generate a basic one
 	if (type == PPSIM_TYPE_OBJECT) {
-	    // XXX TBD : ppSimSetPSF (chip, config);
+	    if (!ppSimSetPSF (chip, config)) {
+		psError(PS_ERR_UNKNOWN, false, "failed IO for chip %d in ppSim\n", view->chip);
+		psFree (view);
+		return false;
+	    }
 	}
 
@@ -64,5 +67,5 @@
                 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "CELL.READDIR = 1 is the only supported mode.");
                 psFree(rng);
-                return PS_EXIT_CONFIG_ERROR;
+                return false;
             }
 
@@ -90,8 +93,4 @@
 		ppSimMakeSky (readout, expCorr, type, config);
 		if (type == PPSIM_TYPE_FLAT) goto done;
-
-		// if (type == PPSIM_TYPE_OBJECT) {
-		// ppSimInsertStars (readout, expCorr, stars, config, chip, cell);
-		// }
 
 		if (type == PPSIM_TYPE_OBJECT) {
@@ -123,5 +122,6 @@
                 psFree(rng);
                 psFree(view);
-                return PS_EXIT_SYS_ERROR;
+                // return PS_EXIT_SYS_ERROR;
+                return false;
             }
         }
@@ -135,5 +135,6 @@
             psFree(rng);
             psFree(view);
-            return PS_EXIT_SYS_ERROR;
+            // return PS_EXIT_SYS_ERROR;
+            return false;
         }
 
@@ -148,5 +149,6 @@
         psFree(rng);
         psFree(view);
-        return PS_EXIT_SYS_ERROR;
+        // return PS_EXIT_SYS_ERROR;
+        return false;
     }
 
@@ -154,4 +156,4 @@
     psFree(view);
 
-    return 0;
+    return true;
 }
Index: /branches/eam_branch_20070817/ppSim/src/ppSimSetPSF.c
===================================================================
--- /branches/eam_branch_20070817/ppSim/src/ppSimSetPSF.c	(revision 14614)
+++ /branches/eam_branch_20070817/ppSim/src/ppSimSetPSF.c	(revision 14614)
@@ -0,0 +1,78 @@
+# include "ppSim.h"
+static char *defaultModel = "PS_MODEL_GAUSS";
+
+bool ppSimSetPSF (pmChip *chip, pmConfig *config) {
+
+    bool status;
+    pmPSF *psf = NULL;
+    psPolynomial2D *param = NULL;
+
+    // the pmPSF IO functions stores the PSF on the chip->analysis
+    psf = psMetadataLookupPtr (&status, chip->analysis, "PSPHOT.PSF");
+    if (psf) {
+	return true;
+    }
+
+    // no supplied PSF, build one using supplied value for seeing
+    // XXX need to correct for the pixel scale
+    float seeing   = psMetadataLookupF32(&status, config->arguments, "SEEING"); // Seeing sigma (pix)
+
+    char *psfModelName = psMetadataLookupStr(&status, config->arguments, "PSF.MODEL"); // Seeing sigma (pix)
+    if (psfModelName == NULL) {
+	psfModelName = defaultModel;
+    }
+
+    pmModelType type = pmModelClassGetType (psfModelName);
+    if (type == -1) {
+	psError (PS_ERR_UNKNOWN, false, "invalid model name");
+        return false;
+    }
+
+    // generate a psf with no spatial variation
+    psf = pmPSFAlloc (type, true, NULL);
+    for (int i = 0; i < psf->params->n; i++) {
+	
+            if (i == PM_PAR_SKY)  continue;
+            if (i == PM_PAR_I0)   continue;
+            if (i == PM_PAR_XPOS) continue;
+            if (i == PM_PAR_YPOS) continue;
+
+	    // generate a 'constant' polynomial, unmasked
+            param = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 0, 0);
+	    param->mask[0][0] = 0;
+
+            psf->params->data[i] = param;
+    }
+
+    psEllipseAxes axes;
+    psEllipsePol pol;
+    
+    // supply the semi-major axis
+    axes.major = seeing / 2.0;
+    axes.minor = seeing / 2.0;
+    axes.theta = 0.0;
+
+    pol = psEllipseAxesToPol (axes);
+
+    param = psf->params->data[PM_PAR_E0];
+    param->coeff[0][0] = pol.e0;
+
+    param = psf->params->data[PM_PAR_E1];
+    param->coeff[0][0] = pol.e1;
+
+    param = psf->params->data[PM_PAR_E2];
+    param->coeff[0][0] = pol.e2;
+
+    if (!strcasecmp (psfModelName, "PS_MODEL_QGAUSS")) {
+	param = psf->params->data[PM_PAR_7];
+	param->coeff[0][0] = 1.0;
+    }
+
+    if (!strcasecmp (psfModelName, "PS_MODEL_RGAUSS")) {
+	param = psf->params->data[PM_PAR_7];
+	param->coeff[0][0] = 1.0;
+    }
+
+    psMetadataAdd (chip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN,  "psphot psf", psf);
+    return true;
+}
