Index: branches/simmosaic_branches/psphot/src/psphotOutput.c
===================================================================
--- branches/simmosaic_branches/psphot/src/psphotOutput.c	(revision 24860)
+++ branches/simmosaic_branches/psphot/src/psphotOutput.c	(revision 27839)
@@ -31,4 +31,36 @@
     }
     return background;
+}
+
+// dump source stats for psf stars
+bool psphotDumpStats (psArray *sources, char *stage) {
+
+    char filename[64];
+    snprintf (filename, 64, "psf.%s.dat", stage);
+    FILE *f = fopen (filename, "w");
+    for (int i = 0; i < sources->n; i++) {
+	pmSource *source = sources->data[i];
+	if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
+
+	pmModel *model = source->modelPSF;
+	if (!model) continue;
+
+	// int xc = source->peak->x - source->pixels->col0;
+	// int yc = source->peak->y - source->pixels->row0;
+	// float mcore = source->modelFlux ? source->modelFlux->data.F32[yc][xc] : NAN;
+	// float mpeak = model ? model->params->data.F32[PM_PAR_I0] : NAN;
+	// bool subtracted = source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED;
+	// fprintf (stderr, "%d %d : %d : %f %f : %f %f\n", source->peak->x, source->peak->y, subtracted, source->peak->flux, source->pixels->data.F32[yc][xc], mcore, mpeak); 
+
+	fprintf (f, "%6.1f %6.1f : %6.1f %6.1f : %8.3f %8.3f %8.3f : %f : %f %f %f : %f\n",
+		 source->peak->xf, source->peak->yf, 
+		 model->params->data.F32[PM_PAR_XPOS], model->params->data.F32[PM_PAR_YPOS], 
+		 source->psfMag, source->apMag, source->errMag,
+		 model->params->data.F32[PM_PAR_I0], 
+		 model->params->data.F32[PM_PAR_SXX], model->params->data.F32[PM_PAR_SXY], model->params->data.F32[PM_PAR_SYY], 
+		 model->params->data.F32[PM_PAR_7]);
+    }
+    fclose (f);
+    return true;
 }
 
@@ -94,16 +126,33 @@
 }
 
-bool psphotAddPhotcode (psMetadata *recipe, pmConfig *config, const pmFPAview *view, const char *filerule) {
-
-    bool status;
-
-    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, filerule);
-    PS_ASSERT (status, false);
-
-    // determine PHOTCODE from fpa & view, overwrite in recipe
-    char *photcode = pmConceptsPhotcodeForView (input, view);
+bool psphotAddPhotcode (pmConfig *config, const pmFPAview *view) {
+
+    bool status = false;
+
+    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
+    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
+
+    // loop over the available readouts
+    for (int i = 0; i < num; i++) {
+	if (!psphotAddPhotcodeReadout (config, view, "PSPHOT.INPUT", i)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed to add photcode to PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
+bool psphotAddPhotcodeReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index) {
+
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, index); // File of interest
+    PS_ASSERT (file, false);
+
+    pmReadout  *readout = pmFPAviewThisReadout (view, file->fpa);
+
+    // determine PHOTCODE from fpa & view, overwrite in readout->analysis
+    char *photcode = pmConceptsPhotcodeForView (file, view);
     PS_ASSERT (photcode, false);
 
-    psMetadataAddStr (recipe, PS_LIST_TAIL, "PHOTCODE", PS_META_REPLACE, "photcode from FPA concepts", photcode);
+    psMetadataAddStr (readout->analysis, PS_LIST_TAIL, "PHOTCODE", PS_META_REPLACE, "photcode from FPA concepts", photcode);
     psLogMsg ("psphot", 3, "PHOTCODE is %s", photcode);
 
@@ -112,5 +161,5 @@
 }
 
-bool psphotSetHeaderNstars (psMetadata *recipe, psArray *sources) {
+bool psphotSetHeaderNstars (psMetadata *header, psArray *sources) {
 
     int nSrc = 0;
@@ -141,95 +190,93 @@
     }
 
-    psMetadataAddS32 (recipe, PS_LIST_TAIL, "NSTARS",   PS_META_REPLACE, "Number of sources", nSrc);
-    psMetadataAddS32 (recipe, PS_LIST_TAIL, "NDET_EXT", PS_META_REPLACE, "Number of extended sources", nEXT);
-    psMetadataAddS32 (recipe, PS_LIST_TAIL, "NDET_CR",  PS_META_REPLACE, "Number of cosmic rays", nCR);
-    return true;
-}
-
-// these values are saved in an output header stub - they are added to either the
-// PHU header (CMP) or the MEF table header (CMF)
-psMetadata *psphotDefineHeader (psMetadata *recipe) {
+    psMetadataAddS32 (header, PS_LIST_TAIL, "NSTARS",   PS_META_REPLACE, "Number of sources", nSrc);
+    psMetadataAddS32 (header, PS_LIST_TAIL, "NDET_EXT", PS_META_REPLACE, "Number of extended sources", nEXT);
+    psMetadataAddS32 (header, PS_LIST_TAIL, "NDET_CR",  PS_META_REPLACE, "Number of cosmic rays", nCR);
+    return true;
+}
+
+// these values are saved in an output header stub - they are added to either the PHU header
+// (CMP) or the MEF table header (CMF).  before the header is created, each readout has these
+// values stored on readout->analysis
+psMetadata *psphotDefineHeader (psMetadata *analysis) {
+
+    bool status = true;
 
     psMetadata *header = psMetadataAlloc ();
 
     // write necessary information to output header
-    psMetadataItemSupplement (header, recipe, "ZERO_PT");
-    psMetadataItemSupplement (header, recipe, "PHOTCODE");
-
-    psMetadataItemSupplement (header, recipe, "APMIFIT");
-    psMetadataItemSupplement (header, recipe, "DAPMIFIT");
-    psMetadataItemSupplement (header, recipe, "NAPMIFIT");
-    psMetadataItemSupplement (header, recipe, "SKYBIAS");
-    psMetadataItemSupplement (header, recipe, "SKYSAT");
+    psMetadataItemSupplement (&status, header, analysis, "ZERO_PT");
+    psMetadataItemSupplement (&status, header, analysis, "PHOTCODE");
+
+    psMetadataItemSupplement (&status, header, analysis, "APMIFIT");
+    psMetadataItemSupplement (&status, header, analysis, "DAPMIFIT");
+    psMetadataItemSupplement (&status, header, analysis, "NAPMIFIT");
 
     // PSF model parameters (shape values for image center)
-    psMetadataItemSupplement (header, recipe, "NPSFSTAR");
-    psMetadataItemSupplement (header, recipe, "APLOSS");
-
-    psMetadataItemSupplement (header, recipe, "FWHM_MAJ");
-    psMetadataItemSupplement (header, recipe, "FW_MJ_SG");
-    psMetadataItemSupplement (header, recipe, "FW_MJ_LQ");
-    psMetadataItemSupplement (header, recipe, "FW_MJ_UQ");
-
-    psMetadataItemSupplement (header, recipe, "FWHM_MIN");
-    psMetadataItemSupplement (header, recipe, "FW_MN_SG");
-    psMetadataItemSupplement (header, recipe, "FW_MN_LQ");
-    psMetadataItemSupplement (header, recipe, "FW_MN_UQ");
-
-    psMetadataItemSupplement (header, recipe, "ANGLE");
+    psMetadataItemSupplement (&status, header, analysis, "NPSFSTAR");
+    psMetadataItemSupplement (&status, header, analysis, "APLOSS");
+
+    psMetadataItemSupplement (&status, header, analysis, "FWHM_MAJ");
+    psMetadataItemSupplement (&status, header, analysis, "FW_MJ_SG");
+    psMetadataItemSupplement (&status, header, analysis, "FW_MJ_LQ");
+    psMetadataItemSupplement (&status, header, analysis, "FW_MJ_UQ");
+
+    psMetadataItemSupplement (&status, header, analysis, "FWHM_MIN");
+    psMetadataItemSupplement (&status, header, analysis, "FW_MN_SG");
+    psMetadataItemSupplement (&status, header, analysis, "FW_MN_LQ");
+    psMetadataItemSupplement (&status, header, analysis, "FW_MN_UQ");
+
+    psMetadataItemSupplement (&status, header, analysis, "ANGLE");
 
     // Image Quality measurements
-    psMetadataItemSupplement (header, recipe, "IQ_NSTAR");
-
-    psMetadataItemSupplement (header, recipe, "IQ_FW1");
-    psMetadataItemSupplement (header, recipe, "IQ_FW1_E");
-    psMetadataItemSupplement (header, recipe, "IQ_FW2");
-    psMetadataItemSupplement (header, recipe, "IQ_FW2_E");
-
-    psMetadataItemSupplement (header, recipe, "IQ_M2");
-    psMetadataItemSupplement (header, recipe, "IQ_M2_ER");
-    psMetadataItemSupplement (header, recipe, "IQ_M2_LQ");
-    psMetadataItemSupplement (header, recipe, "IQ_M2_UQ");
-
-    psMetadataItemSupplement (header, recipe, "IQ_M2C");
-    psMetadataItemSupplement (header, recipe, "IQ_M2C_E");
-    psMetadataItemSupplement (header, recipe, "IQ_M2C_L");
-    psMetadataItemSupplement (header, recipe, "IQ_M2C_U");
-
-    psMetadataItemSupplement (header, recipe, "IQ_M2S");
-    psMetadataItemSupplement (header, recipe, "IQ_M2S_E");
-    psMetadataItemSupplement (header, recipe, "IQ_M2S_L");
-    psMetadataItemSupplement (header, recipe, "IQ_M2S_U");
-
-    psMetadataItemSupplement (header, recipe, "IQ_M3");
-    psMetadataItemSupplement (header, recipe, "IQ_M3_ER");
-    psMetadataItemSupplement (header, recipe, "IQ_M3_LQ");
-    psMetadataItemSupplement (header, recipe, "IQ_M3_UQ");
-
-    psMetadataItemSupplement (header, recipe, "IQ_M4");
-    psMetadataItemSupplement (header, recipe, "IQ_M4_ER");
-    psMetadataItemSupplement (header, recipe, "IQ_M4_LQ");
-    psMetadataItemSupplement (header, recipe, "IQ_M4_UQ");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_NSTAR");
+
+    psMetadataItemSupplement (&status, header, analysis, "IQ_FW1");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_FW1_E");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_FW2");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_FW2_E");
+
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2_ER");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2_LQ");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2_UQ");
+
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2C");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2C_E");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2C_L");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2C_U");
+
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2S");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2S_E");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2S_L");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M2S_U");
+
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M3");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M3_ER");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M3_LQ");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M3_UQ");
+
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M4");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M4_ER");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M4_LQ");
+    psMetadataItemSupplement (&status, header, analysis, "IQ_M4_UQ");
 
     // XXX these need to be defined from elsewhere
     psMetadataAdd (header, PS_LIST_TAIL, "FSATUR",   PS_DATA_F32 | PS_META_REPLACE, "SATURATION MAG",      0.0);
     psMetadataAdd (header, PS_LIST_TAIL, "FLIMIT",   PS_DATA_F32 | PS_META_REPLACE, "COMPLETENESS MAG",    0.0);
-    psMetadataItemSupplement (header, recipe, "NSTARS");
-
-    psMetadataItemSupplement (header, recipe, "NDET_EXT");
-    psMetadataItemSupplement (header, recipe, "NDET_CR");
+    psMetadataItemSupplement (&status, header, analysis, "NSTARS");
+
+    psMetadataItemSupplement (&status, header, analysis, "NDET_EXT");
+    psMetadataItemSupplement (&status, header, analysis, "NDET_CR");
 
     // sky background model statistics
-    psMetadataItemSupplement (header, recipe, "MSKY_MN");
-    psMetadataItemSupplement (header, recipe, "MSKY_SIG");
-    psMetadataItemSupplement (header, recipe, "MSKY_MIN");
-    psMetadataItemSupplement (header, recipe, "MSKY_MAX");
-    psMetadataItemSupplement (header, recipe, "MSKY_NX");
-    psMetadataItemSupplement (header, recipe, "MSKY_NY");
+    psMetadataItemSupplement (&status, header, analysis, "MSKY_MN");
+    psMetadataItemSupplement (&status, header, analysis, "MSKY_SIG");
+    psMetadataItemSupplement (&status, header, analysis, "MSKY_MIN");
+    psMetadataItemSupplement (&status, header, analysis, "MSKY_MAX");
+    psMetadataItemSupplement (&status, header, analysis, "MSKY_NX");
+    psMetadataItemSupplement (&status, header, analysis, "MSKY_NY");
 
     psMetadataAddF32 (header, PS_LIST_TAIL, "DT_PHOT", PS_META_REPLACE, "elapsed psphot time", psTimerMark ("psphotReadout"));
-
-    // XXX : don't require any of these about values to exist
-    psErrorClear ();
 
     return header;
@@ -256,5 +303,5 @@
         psImageKeepCircle (source->maskObj, x, y, radius, "OR", markVal);
         pmModelSub (source->pixels, source->maskObj, source->modelPSF, PM_MODEL_OP_FULL, maskVal);
-        psImageKeepCircle (source->maskObj, x, y, radius, "AND", PS_NOT_IMAGE_MASK(markVal));
+        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
     }
 
