Index: /branches/eam_branches/psphot.stack.20100120/doc/stack.txt
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/doc/stack.txt	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/doc/stack.txt	(revision 26688)
@@ -24,4 +24,10 @@
     can we use the processing flags to distinguish the these cases and carry around 
     only a single source list?
+
+    * detections->peaks holds the most recently detected set of peaks
+      detections->oldPeaks holds the previous collection
+
+      detections->footprints holds the full set of merged footprints,
+      including assigned peaks from the old and new set.
 
 20100107 : updates for stack processing
Index: /branches/eam_branches/psphot.stack.20100120/src/Makefile.am
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/Makefile.am	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/Makefile.am	(revision 26688)
@@ -33,19 +33,19 @@
 psphot_LDADD = libpsphot.la
 
-psphotForced_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
-psphotForced_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
-psphotForced_LDADD = libpsphot.la
-
-psphotMakePSF_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
-psphotMakePSF_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
-psphotMakePSF_LDADD = libpsphot.la
-
-psphotTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
-psphotTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
-psphotTest_LDADD = libpsphot.la
-
-psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
-psphotMomentsStudy_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
-psphotMomentsStudy_LDADD = libpsphot.la
+# psphotForced_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
+# psphotForced_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
+# psphotForced_LDADD = libpsphot.la
+# 
+# psphotMakePSF_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
+# psphotMakePSF_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
+# psphotMakePSF_LDADD = libpsphot.la
+# 
+# psphotTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
+# psphotTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
+# psphotTest_LDADD = libpsphot.la
+# 
+# psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
+# psphotMomentsStudy_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
+# psphotMomentsStudy_LDADD = libpsphot.la
 
 # psphotPetrosianStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
@@ -62,40 +62,40 @@
 	psphotCleanup.c
 
-# forced photometry of specified positions given a specified psf
-psphotForced_SOURCES = \
-        psphotForced.c             \
-	psphotForcedArguments.c	   \
-	psphotForcedImageLoop.c	   \
-	psphotForcedReadout.c	   \
-	psphotParseCamera.c        \
-	psphotMosaicChip.c	   \
-	psphotCleanup.c
-
-# a psphot-variant that simply generates the PSF model
-psphotMakePSF_SOURCES = \
-        psphotMakePSF.c            \
-	psphotMakePSFArguments.c   \
-	psphotMakePSFImageLoop.c   \
-	psphotMakePSFReadout.c	   \
-	psphotParseCamera.c        \
-	psphotMosaicChip.c	   \
-	psphotCleanup.c
-
-
-# psphot analysis of the detectability of specified positions
-psphotDetect_SOURCES =            \
-        psphotDetect.c            \
-	psphotDetectArguments.c	  \
-	psphotDetectParseCamera.c \
-	psphotDetectImageLoop.c	  \
-	psphotDetectReadout.c	  \
-	psphotMosaicChip.c	  \
-	psphotCleanup.c
-
-psphotTest_SOURCES = \
-        psphotTest.c
-
-psphotMomentsStudy_SOURCES = \
-        psphotMomentsStudy.c
+# # forced photometry of specified positions given a specified psf
+# psphotForced_SOURCES = \
+#         psphotForced.c             \
+# 	psphotForcedArguments.c	   \
+# 	psphotForcedImageLoop.c	   \
+# 	psphotForcedReadout.c	   \
+# 	psphotParseCamera.c        \
+# 	psphotMosaicChip.c	   \
+# 	psphotCleanup.c
+# 
+# # a psphot-variant that simply generates the PSF model
+# psphotMakePSF_SOURCES = \
+#         psphotMakePSF.c            \
+# 	psphotMakePSFArguments.c   \
+# 	psphotMakePSFImageLoop.c   \
+# 	psphotMakePSFReadout.c	   \
+# 	psphotParseCamera.c        \
+# 	psphotMosaicChip.c	   \
+# 	psphotCleanup.c
+# 
+# 
+# # psphot analysis of the detectability of specified positions
+# psphotDetect_SOURCES =            \
+#         psphotDetect.c            \
+# 	psphotDetectArguments.c	  \
+# 	psphotDetectParseCamera.c \
+# 	psphotDetectImageLoop.c	  \
+# 	psphotDetectReadout.c	  \
+# 	psphotMosaicChip.c	  \
+# 	psphotCleanup.c
+# 
+# psphotTest_SOURCES = \
+#         psphotTest.c
+# 
+# psphotMomentsStudy_SOURCES = \
+#         psphotMomentsStudy.c
 
 # psphotPetrosianStudy_SOURCES = \
Index: /branches/eam_branches/psphot.stack.20100120/src/psphot.h
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphot.h	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphot.h	(revision 26688)
@@ -12,4 +12,12 @@
 
 #define PSPHOT_RECIPE_PSF_FAKE_ALLOW "PSF.FAKE.ALLOW" // Name for recipe component permitting fake PSFs
+
+// pmPCMData : PSF Convolved Model data storage structure
+typedef struct {
+    psImage *model;
+    psArray *dmodels;
+    psImage *modelConv;
+    psArray *dmodelsConv;
+} pmPCMData;
 
 // top-level psphot functions
@@ -38,68 +46,124 @@
 // XXX test functions
 psArray        *psphotFakeSources (void);
-bool psphotMaskCosmicRayFootprintCheck (psArray *sources);
+bool 	        psphotMaskCosmicRayFootprintCheck (psArray *sources);
 
 // psphotReadout functions
+bool            psphotAddPhotcode (pmConfig *config, const pmFPAview *view);
+bool            psphotAddPhotcodeReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index);
+
+bool            psphotSetMaskAndVariance (pmConfig *config, const pmFPAview *view, psMetadata *recipe);
+bool            psphotSetMaskAndVarianceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
 bool            psphotModelBackground (pmConfig *config, const pmFPAview *view);
 bool            psphotModelBackgroundReadoutFileIndex (pmConfig *config, const pmFPAview *view, const char *filename, int index);
 
-// Create a background model for a readout, without saving the result as a pmFPAfile on
-// config->files.  Otherwise identical to psphotModelBackgroundFileIndex.
-psImage        *psphotModelBackgroundReadoutNoFile(pmReadout *readout, const pmConfig *config);
-
-// worker function for above background model functions
-bool psphotModelBackgroundReadout(psImage *model,  // Model image
-				  psImage *modelStdev, // Model stdev image
-				  psMetadata *analysis, // Analysis metadata for outputs
-				  pmReadout *readout, // Readout for which to generate a background model
-				  psImageBinning *binning, // Binning parameters
-				  const pmConfig *config // Configuration
-    );
-
-psImageBinning *psphotBackgroundBinning(const psImage *, const pmConfig *);
-
-
-
 bool            psphotSubtractBackground (pmConfig *config, const pmFPAview *view);
-bool            psphotSubtractBackgroundReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index);
-
-
-pmDetections   *psphotFindDetections (pmDetections *detections, pmReadout *readout, psMetadata *recipe);
-
-bool            psphotRoughClass (pmReadout *readout, psArray *sources, psMetadata *recipe, const bool findPsfClump);
-bool            psphotBasicDeblend (psArray *sources, psMetadata *recipe);
-pmPSF          *psphotChoosePSF (pmReadout *readout, psArray *sources, psMetadata *recipe);
+bool            psphotSubtractBackgroundReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool		psphotFindDetections (pmConfig *config, const pmFPAview *view);
+bool 		psphotFindDetectionsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool		psphotSourceStats (pmConfig *config, const pmFPAview *view, bool setWindow);
+bool 		psphotSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool setWindow);
+
+bool 		psphotDeblendSatstars (pmConfig *config, const pmFPAview *view);
+bool 		psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index);
+
+bool 		psphotBasicDeblend (pmConfig *config, const pmFPAview *view);
+bool 		psphotBasicDeblend (pmConfig *config, const pmFPAview *view, const char *filename, int index);
+
+bool 		psphotRoughClass (pmConfig *config, const pmFPAview *view);
+bool 		psphotRoughClassReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+bool 		psphotRoughClassRegion (int nRegion, psRegion *region, psArray *sources, psMetadata *analysis, psMetadata *recipe, const bool havePSF);
+
+bool 		psphotImageQuality (pmConfig *config, const pmFPAview *view);
+bool 		psphotImageQualityReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool 		psphotChoosePSF (pmConfig *config, const pmFPAview *view);
+bool 		psphotChoosePSFReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool 		psphotGuessModels (pmConfig *config, const pmFPAview *view);
+bool 		psphotGuessModelsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index);
+
+bool 		psphotMergeSources (pmConfig *config, const pmFPAview *view);
+bool 		psphotMergeSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index);
+
+bool 		psphotFitSourcesLinear (pmConfig *config, const pmFPAview *view, bool final);
+bool 		psphotFitSourcesLinearReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index);
+
+bool 		psphotSourceSize (pmConfig *config, const pmFPAview *view, bool getPSFsize);
+bool 		psphotSourceSizeReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool getPSFsize);
+
+bool 		psphotBlendFit (pmConfig *config, const pmFPAview *view);
+bool 		psphotBlendFitReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+bool            psphotBlendFit_Threaded (psThreadJob *job);
+
+bool 		psphotReplaceAllSources (pmConfig *config, const pmFPAview *view);
+bool 		psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool 		psphotAddNoise (pmConfig *config, const pmFPAview *view);
+bool 		psphotSubNoise (pmConfig *config, const pmFPAview *view);
+bool 		psphotAddOrSubNoise (pmConfig *config, const pmFPAview *view, bool add);
+bool 		psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool add);
+
+bool 		psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view);
+bool 		psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool 		psphotExtendedSourceFits (pmConfig *config, const pmFPAview *view);
+bool 		psphotExtendedSourceFitsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool 		psphotApResid (pmConfig *config, const pmFPAview *view);
+bool 		psphotApResid (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool 		psphotMagnitudes (pmConfig *config, const pmFPAview *view);
+bool 		psphotMagnitudesReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+bool            psphotMagnitudes_Threaded (psThreadJob *job);
+
+bool 		psphotEfficiency (pmConfig *config, const pmFPAview *view);
+bool 		psphotEfficiencyReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe);
+
+bool            psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources);
+bool            psphotPSFWeights_Threaded (psThreadJob *job);
+
+bool 		psphotSkyReplace (pmConfig *config, const pmFPAview *view);
+bool 		psphotSkyReplaceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index);
+
+bool 		psphotSourceFreePixels (pmConfig *config, const pmFPAview *view);
+bool 		psphotSourceFreePixelsReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index);
+
+// in psphotSourceStats.c:
+bool            psphotSourceStats_Threaded (psThreadJob *job);
+bool            psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout);
+bool 		psphotSetMomentsWindow (psMetadata *recipe, psMetadata *analysis, psArray *sources);
+
+// in psphotChoosePSF.c:
 bool            psphotPSFstats (pmReadout *readout, psMetadata *recipe, pmPSF *psf);
 bool            psphotMomentsStats (pmReadout *readout, psMetadata *recipe, psArray *sources);
-bool            psphotFitSourcesLinear (pmReadout *readout, psArray *sources, const psMetadata *recipe, const pmPSF *psf, bool final);
+
+// in psphotGuessModel.c
+bool		psphotGuessModel_Threaded (psThreadJob *job);
+
+// in psphotMergeSources.c:
+bool            psphotLoadExtSources (pmConfig *config, const pmFPAview *view, psArray *sources);
+psArray        *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view);
+
+// generate the detection structure for the supplied array of sources
+pmDetections   *psphotDetectionsFromSources (pmConfig *config, psArray *sources);
+
+// generate the detection structure for the supplied array of sources
+bool 	        psphotSetSourceParams (pmConfig *config, psArray *sources, pmPSF *psf);
+
+// in psphotModelBackground.c:
+// Create a background model for a readout, without saving the result as a pmFPAfile on config->files.  Otherwise identical to psphotModelBackgroundFileIndex.
+psImage        *psphotModelBackgroundReadoutNoFile(pmReadout *readout, const pmConfig *config);
+psImageBinning *psphotBackgroundBinning(const psImage *, const pmConfig *);
+
+// in psphotReplaceUnfit.c:
+bool            psphotRemoveAllSources (const psArray *sources, const psMetadata *recipe);
+bool 		psphotReplaceUnfitSources (psArray *sources, psImageMaskType maskVal);
 bool            psphotReplaceUnfitSources (psArray *sources, psImageMaskType maskVal);
-
-bool psphotSetMomentsWindow (psMetadata *recipe, psMetadata *analysis, psArray *sources);
 
 bool            psphotReplaceAllSources (psArray *sources, psMetadata *recipe);
 bool            psphotRemoveAllSources (const psArray *sources, const psMetadata *recipe);
-
-bool            psphotBlendFit (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf);
-bool            psphotBlendFit_Threaded (psThreadJob *job);
-
-bool            psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout);
-psArray        *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections, bool setWindow);
-bool            psphotSourceStats_Threaded (psThreadJob *job);
-
-bool            psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf);
-bool            psphotGuessModel_Threaded (psThreadJob *job);
-
-bool            psphotMagnitudes (pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, const pmPSF *psf);
-bool            psphotMagnitudes_Threaded (psThreadJob *job);
-
-bool            psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources);
-bool            psphotPSFWeights_Threaded (psThreadJob *job);
-
-bool            psphotApResid (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf);
-
-bool            psphotSkyReplace (pmConfig *config, const pmFPAview *view);
-bool            psphotExtendedSourceAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe);
-bool            psphotExtendedSourceFits (pmReadout *readout, psArray *sources, psMetadata *recipe);
-bool            psphotEfficiency(pmConfig *config, pmReadout *readout, const pmFPAview *view, const pmPSF *psf, psMetadata *recipe, const psArray *realSources);
 
 // thread-related:
@@ -115,8 +179,5 @@
 psErrorCode     psphotCullPeaks(const psImage *img, const psImage *weight, const psMetadata *recipe, psArray *footprints);
 
-// generate the detection structure for the supplied array of sources
-pmDetections   *psphotDetectionsFromSources (pmConfig *config, psArray *sources);
-
-// used by ApResid
+// in psphotApResid.c:
 pmTrend2D      *psphotApResidTrend (float *apResidSysErr, pmReadout *readout, int Nx, int Ny, psVector *xPos, psVector *yPos, psVector *apResid, psVector *dMag);
 bool            psphotApResidMags_Threaded (psThreadJob *job);
@@ -125,9 +186,5 @@
 void            psphotModelClassInit (void);
 bool            psphotGrowthCurve (pmReadout *readout, pmPSF *psf, bool ignore, psImageMaskType maskVal);
-bool            psphotSetMaskAndVariance (pmConfig *config, const pmFPAview *view, psMetadata *recipe);
-bool            psphotSetMaskAndVarianceReadout (pmConfig *config, pmReadout *readout, psMetadata *recipe);
 void            psphotSourceFreePixels (psArray *sources);
-
-bool psphotRoughClassRegion (int nRegion, psRegion *region, psArray *sources, psMetadata *target, psMetadata *recipe, const bool havePSF);
 
 // functions to set the correct source pixels
@@ -138,8 +195,4 @@
 bool            psphotCheckRadiusEXT (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal);
 float           psphotSetRadiusEXT (pmReadout *readout, pmSource *source, psImageMaskType markVal);
-
-// output functions
-bool            psphotAddPhotcodeReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index);
-bool            psphotAddPhotcode (pmConfig *config, const pmFPAview *view);
 
 bool            psphotDumpMoments (psMetadata *recipe, psArray *sources);
@@ -173,8 +226,4 @@
 bool            psphotFitSummary (void);
 
-bool            psphotMergeSources (psArray *oldSources, psArray *newSources);
-bool            psphotLoadExtSources (pmConfig *config, const pmFPAview *view, psArray *sources);
-psArray        *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view);
-
 pmPSF          *psphotLoadPSF (pmConfig *config, const pmFPAview *view, psMetadata *recipe);
 bool            psphotSetHeaderNstars (psMetadata *recipe, psArray *sources);
@@ -186,10 +235,4 @@
 bool            psphotMosaicSubimage (psImage *outImage, pmSource *source, int Xo, int Yo, int DX, int DY, bool normalize);
 
-bool            psphotAddWithTest (pmSource *source, bool useState, psImageMaskType maskVal);
-bool            psphotSubWithTest (pmSource *source, bool useState, psImageMaskType maskVal);
-bool            psphotSetState (pmSource *source, bool curState, psImageMaskType maskVal);
-bool            psphotDeblendSatstars (pmReadout *readout, psArray *sources, psMetadata *recipe);
-bool            psphotSourceSize (pmConfig *config, pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, long first);
-
 bool            psphotMakeResiduals (psArray *sources, psMetadata *recipe, pmPSF *psf, psImageMaskType maskVal);
 
@@ -199,35 +242,33 @@
 
 // functions related to extended source analysis
-bool  psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal);
-bool  psphotRadialProfilesByAngles (pmSource *source, int Nsec, float Rmax);
-float psphotRadiusFromProfile (pmSource *source, psVector *radius, psVector *flux, float fluxMin, float fluxMax);
-bool  psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax);
-bool  psphotEllipticalProfile (pmSource *source);
-bool  psphotEllipticalContour (pmSource *source);
+bool  	        psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal);
+bool  		psphotRadialProfilesByAngles (pmSource *source, int Nsec, float Rmax);
+float 		psphotRadiusFromProfile (pmSource *source, psVector *radius, psVector *flux, float fluxMin, float fluxMax);
+bool  		psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax);
+bool  		psphotEllipticalProfile (pmSource *source);
+bool  		psphotEllipticalContour (pmSource *source);
 
 // psphotVisual functions
-bool psphotVisualShowImage (pmReadout *readout);
-bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout);
-bool psphotVisualShowSignificance (psImage *image, float min, float max);
-bool psphotVisualShowPeaks (pmDetections *detections);
-bool psphotVisualShowFootprints (pmDetections *detections);
-bool psphotVisualShowMoments (psArray *sources);
-bool psphotVisualPlotMoments (psMetadata *recipe, psMetadata *analysis, psArray *sources);
-bool psphotVisualShowRoughClass (psArray *sources);
-bool psphotVisualShowPSFStars (psMetadata *recipe, pmPSF *psf, psArray *sources);
-bool psphotVisualShowSatStars (psMetadata *recipe, pmPSF *psf, psArray *sources);
-bool psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf);
-bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal);
-bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources);
-bool psphotVisualShowFlags (psArray *sources);
-bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources);
-bool psphotVisualShowResidualImage (pmReadout *readout);
-bool psphotVisualPlotApResid (psArray *sources, float mean, float error);
-bool psphotVisualPlotChisq (psArray *sources);
-bool psphotVisualPlotSourceSize (psMetadata *recipe, psMetadata *analysis, psArray *sources);
-bool psphotVisualShowPetrosians (psArray *sources);
-
-// bool psphotPetrosianAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe);
-// bool psphotPetrosianProfile (pmReadout *readout, pmSource *source, float skynoise);
+bool            psphotVisualShowImage (pmReadout *readout);
+bool 		psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout);
+bool 		psphotVisualShowSignificance (psImage *image, float min, float max);
+bool 		psphotVisualShowPeaks (pmDetections *detections);
+bool 		psphotVisualShowFootprints (pmDetections *detections);
+bool 		psphotVisualShowMoments (psArray *sources);
+bool 		psphotVisualPlotMoments (psMetadata *recipe, psMetadata *analysis, psArray *sources);
+bool 		psphotVisualShowRoughClass (psArray *sources);
+bool 		psphotVisualShowPSFStars (psMetadata *recipe, pmPSF *psf, psArray *sources);
+bool 		psphotVisualShowSatStars (psMetadata *recipe, pmPSF *psf, psArray *sources);
+bool 		psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf);
+bool 		psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal);
+bool 		psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources);
+bool 		psphotVisualShowFlags (psArray *sources);
+bool 		psphotVisualShowSourceSize (pmReadout *readout, psArray *sources);
+bool 		psphotVisualShowResidualImage (pmReadout *readout);
+bool 		psphotVisualPlotApResid (psArray *sources, float mean, float error);
+bool 		psphotVisualPlotChisq (psArray *sources);
+bool 		psphotVisualPlotSourceSize (psMetadata *recipe, psMetadata *analysis, psArray *sources);
+bool 		psphotVisualShowPetrosians (psArray *sources);
+bool 		psphotVisualEraseOverlays (int channel, char *overlay);
 
 bool psphotPetrosian (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal);
@@ -235,5 +276,5 @@
 bool psphotPetrosianStats (pmSource *source);
 
-// XXX old versions, currently disabled
+// currently disabled:
 // bool            psphotIsophotal (pmSource *source, psMetadata *recipe, psImageMaskType maskVal);
 // bool            psphotAnnuli (pmSource *source, psMetadata *recipe, psImageMaskType maskVal);
@@ -250,16 +291,5 @@
 //                               float petFlux, float radiusForFlux);
 
-bool psphotImageQuality (psMetadata *recipe, psArray *sources);
-
 // structures & functions to support psf-convolved model fitting
-
-// pmPCMData : PSF Convolved Model data storage structure
-typedef struct {
-    psImage *model;
-    psArray *dmodels;
-    psImage *modelConv;
-    psArray *dmodelsConv;
-} pmPCMData;
-
 
 // psf-convolved model fitting
@@ -291,5 +321,4 @@
 
 int psphotKapaOpen (void);
-bool psphotVisualEraseOverlays (int channel, char *overlay);
 bool psphotKapaClose (void);
 bool psphotImageBackgroundCellHistogram (psVector *values, float mean, float sigma, int ix, int iy);
@@ -305,5 +334,4 @@
 int psphotSupplementStars (psArray *stars, psArray *sources, psImageBinning *binning, int ix, int iy);
 
-
 pmConfig *psphotForcedArguments(int argc, char **argv);
 bool psphotForcedImageLoop (pmConfig *config);
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotAddNoise.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotAddNoise.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotAddNoise.c	(revision 26688)
@@ -31,5 +31,5 @@
 }
 
-bool psphotAddOrSubNoise (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool add) {
+bool psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool add) {
 
     bool status = false;
@@ -40,5 +40,5 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
@@ -47,5 +47,8 @@
     psAssert (readout->parent->concepts, "missing concepts?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
     psAssert (sources, "missing sources?");
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotApResid.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotApResid.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotApResid.c	(revision 26688)
@@ -4,5 +4,27 @@
 // measure the aperture residual statistics and 2D variations
 
-bool psphotApResid (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf)
+// for now, let's store the detections on the readout->analysis for each readout
+bool psphotApResid (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    int num = psMetadataAddS32 (&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 (!psphottApResidReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
+bool psphotApResid (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe)
 {
     int Nfail = 0;
@@ -13,14 +35,26 @@
     pmSource *source;
 
-    PS_ASSERT_PTR_NON_NULL(config, false);
-    PS_ASSERT_PTR_NON_NULL(readout, false);
-    PS_ASSERT_PTR_NON_NULL(sources, false);
-    PS_ASSERT_PTR_NON_NULL(psf, false);
-
     psTimerStart ("psphot.apresid");
 
-    // select the appropriate recipe information
-    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
-    assert (recipe);
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (readout, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
+    psAssert (sources, "missing sources?");
+
+    if (!sources->n) {
+	psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping ap resid");
+	return true;
+    }
+
+    pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
+    psAssert (psf, "missing psf?");
 
     // determine the number of allowed threads
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotBasicDeblend.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotBasicDeblend.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotBasicDeblend.c	(revision 26688)
@@ -32,10 +32,13 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->newSources;
     psAssert (sources, "missing sources?");
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotBlendFit.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotBlendFit.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotBlendFit.c	(revision 26688)
@@ -36,10 +36,13 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
     psAssert (sources, "missing sources?");
 
@@ -312,109 +315,2 @@
 }
 
-# if (0)
-bool psphotBlendFit_Unthreaded (int *nfit, int *npsf, int *next, int *nfail, pmReadout *readout, psMetadata *recipe, psArray *sources, pmPSF *psf, psArray *newSources) {
-
-    bool status = false;
-    int Nfit = 0;
-    int Npsf = 0;
-    int Next = 0;
-    int Nfail = 0;
-
-    // bit-masks to test for good/bad pixels
-    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
-    assert (maskVal);
-
-    // bit-mask to mark pixels not used in analysis
-    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
-    assert (markVal);
-
-    // maskVal is used to test for rejected pixels, and must include markVal
-    maskVal |= markVal;
-
-    // S/N limit to perform full non-linear fits
-    float FIT_SN_LIM = psMetadataLookupF32 (&status, recipe, "FULL_FIT_SN_LIM");
-
-    // option to limit analysis to a specific region
-    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
-    psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
-    if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
-
-    for (int i = 0; i < sources->n; i++) {
-        pmSource *source = sources->data[i];
-
-        // skip non-astronomical objects (very likely defects)
-        if (source->mode &  PM_SOURCE_MODE_BLEND) continue;
-        if (source->mode &  PM_SOURCE_MODE_CR_LIMIT) continue;
-        if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
-        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
-
-        // skip DBL second sources (ie, added by psphotFitBlob)
-        if (source->mode &  PM_SOURCE_MODE_PAIR) continue;
-
-        // limit selection to some SN limit
-        if (source->peak->SN < FIT_SN_LIM) continue;
-
-        // exclude sources outside optional analysis region
-        if (source->peak->xf < AnalysisRegion.x0) continue;
-        if (source->peak->yf < AnalysisRegion.y0) continue;
-        if (source->peak->xf > AnalysisRegion.x1) continue;
-        if (source->peak->yf > AnalysisRegion.y1) continue;
-
-        // if model is NULL, we don't have a starting guess
-        if (source->modelPSF == NULL) continue;
-
-        // skip sources which are insignificant flux?
-        // XXX this is somewhat ad-hoc
-        if (source->modelPSF->params->data.F32[1] < 0.1) {
-            psTrace ("psphot", 5, "skipping near-zero source: %f, %f : %f\n",
-                     source->modelPSF->params->data.F32[1],
-                     source->modelPSF->params->data.F32[2],
-                     source->modelPSF->params->data.F32[3]);
-            continue;
-        }
-
-        // replace object in image
-        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
-            pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-        }
-        Nfit ++;
-
-        // try fitting PSFs or extended sources depending on source->mode
-        // these functions subtract the resulting fitted source
-        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
-            if (psphotFitBlob (readout, source, newSources, psf, maskVal, markVal)) {
-                source->type = PM_SOURCE_TYPE_EXTENDED;
-                psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf);
-                Next ++;
-                continue;
-            }
-        } else {
-            if (psphotFitBlend (readout, source, psf, maskVal, markVal)) {
-                source->type = PM_SOURCE_TYPE_STAR;
-                psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf);
-                Npsf ++;
-                continue;
-            }
-        }
-
-        psTrace ("psphot", 5, "source at %7.1f, %7.1f failed", source->peak->xf, source->peak->yf);
-        Nfail ++;
-
-        // re-subtract the object, leave local sky
-        pmSourceCacheModel (source, maskVal);
-        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-    }
-
-    // change the value of a scalar on the array (wrap this and put it in psArray.h)
-    *nfit  = Nfit;
-    *npsf  = Npsf;
-    *next  = Next;
-    *nfail = Nfail;
-
-    // moments are modified by the fit; re-display
-    psphotVisualPlotMoments (recipe, sources);
-    psphotVisualShowResidualImage (readout);
-
-    return true;
-}
-# endif
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotChoosePSF.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotChoosePSF.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotChoosePSF.c	(revision 26688)
@@ -38,10 +38,13 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->newSources;
     psAssert (sources, "missing sources?");
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotDeblendSatstars.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotDeblendSatstars.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotDeblendSatstars.c	(revision 26688)
@@ -31,10 +31,13 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->newSources;
     psAssert (sources, "missing sources?");
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotEfficiency.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotEfficiency.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotEfficiency.c	(revision 26688)
@@ -149,15 +149,51 @@
 
 
+bool psphotEfficiency (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    int num = psMetadataAddS32 (&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 (!psphotReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
 // Determine detection efficiency
-bool psphotEfficiency(pmConfig *config, pmReadout *readout, const pmFPAview *view, const pmPSF *psf,
-                psMetadata *recipe, const psArray *realSources)
+bool psphotEfficiencyReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe)
 {
+    psTimerStart("psphot.fake");
+
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (readout, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *realSources = detections->allSources;
+    psAssert (realSources, "missing sources?");
+
+    // XXX do we need to skip this step if we do not have a psf?
+    pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
+    psAssert (psf, "missing psf?");
+
     PM_ASSERT_READOUT_NON_NULL(readout, false);
     PM_ASSERT_READOUT_IMAGE(readout, false);
     PS_ASSERT_PTR_NON_NULL(psf, false);
     PS_ASSERT_METADATA_NON_NULL(recipe, false);
-    PS_ASSERT_ARRAY_NON_NULL(realSources, false);
-
-    psTimerStart("psphot.fake");
 
     // Collect recipe information
@@ -202,5 +238,5 @@
     // remove all sources, adding noise for subtracted sources
     psphotRemoveAllSources(realSources, recipe);
-    //    psphotAddNoise(readout, realSources, recipe);
+    // psphotAddNoise(readout, realSources, recipe);
 
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotExtendedSourceAnalysis.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotExtendedSourceAnalysis.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotExtendedSourceAnalysis.c	(revision 26688)
@@ -1,6 +1,34 @@
 # include "psphotInternal.h"
 
+// for now, let's store the detections on the readout->analysis for each readout
+bool psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    // perform full non-linear fits / extended source analysis?
+    if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANALYSIS")) {
+	psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");
+	return true;
+    }
+
+    int num = psMetadataAddS32 (&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 (!psphotExtendedSourceAnalysisReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
 // aperture-like measurements for extended sources
-bool psphotExtendedSourceAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe) {
+bool psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) {
 
     bool status;
@@ -11,13 +39,25 @@
     int Nkron = 0;
 
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (readout, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
+    psAssert (sources, "missing sources?");
+
+    if (!sources->n) {
+	psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size");
+	return true;
+    }
+
     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
     assert (maskVal);
-
-    // perform full non-linear fits / extended source analysis?
-    if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANALYSIS")) {
-	psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");
-	return true;
-    }
 
     // XXX require petrosian analysis for non-linear fits? 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotExtendedSourceFits.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotExtendedSourceFits.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotExtendedSourceFits.c	(revision 26688)
@@ -1,6 +1,34 @@
 # include "psphotInternal.h"
 
+// for now, let's store the detections on the readout->analysis for each readout
+bool psphotExtendedSourceFits (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    // perform full extended source non-linear fits?
+    if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS")) {
+        psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");
+        return true;
+    }
+
+    int num = psMetadataAddS32 (&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 (!psphotExtendedSourceFitsReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
 // non-linear model fitting for extended sources
-bool psphotExtendedSourceFits (pmReadout *readout, psArray *sources, psMetadata *recipe) {
+bool psphotExtendedSourceFitsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) {
 
     bool status;
@@ -12,4 +40,22 @@
     bool savePics = false;
 
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (readout, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
+    psAssert (sources, "missing sources?");
+
+    if (!sources->n) {
+	psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size");
+	return true;
+    }
+
     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
@@ -21,10 +67,4 @@
     // maskVal is used to test for rejected pixels, and must include markVal
     maskVal |= markVal;
-
-    // perform full extended source non-linear fits?
-    if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS")) {
-        psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");
-        return true;
-    }
 
     // select the collection of desired models
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotFindDetections.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotFindDetections.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotFindDetections.c	(revision 26688)
@@ -1,6 +1,30 @@
 # include "psphotInternal.h"
 
+// we store the detections on the readout->analysis for each readout this function finds new
+// peaks and new footprints.  any old peaks are saved on oldPeaks.  the resulting footprint set
+// contains all footprints (old and new)
+bool psphotFindDetections (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    int num = psMetadataAddS32 (&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 (!psphotFindDetectionsReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed to find initial detections for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
 // smooth the image, search for peaks, optionally define footprints based on the peaks
-bool psphotFindDetections (pmConfig *config, const pmFPAview *view, const char *filename, int index) {
+bool psphotFindDetectionsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) {
 
     bool status;
@@ -11,12 +35,8 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     psAssert (readout, "missing readout?");
-
-    // select the appropriate recipe information
-    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
-    psAssert (recipe, "missing recipe?");
 
     // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
@@ -27,11 +47,21 @@
     const bool useFootprints = psMetadataLookupBool(NULL, recipe, "USE_FOOTPRINTS");
 
-    // on first pass, detections have not yet been allocated
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    // on the initial pass, detections have not yet been allocated or saved on readout->analysis
     if (!detections) {
+	// create the container
         detections = pmDetectionsAlloc();
+	
+	// save detections on the readout->analysis
+	if (!psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_DATA_PTR, "psphot detectinos", detections)) {
+	    psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
+	    return false;
+	}
+
         pass = 1;
         NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT"); PS_ASSERT (status, NULL);
         NMAX = psMetadataLookupS32 (&status, recipe, "PEAKS_NMAX"); PS_ASSERT (status, NULL);
     } else {
+	psMemIncrRefCounter(detections); // so we can free the detections below
         pass = 2;
         NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT_2"); PS_ASSERT (status, NULL);
@@ -41,6 +71,10 @@
     float threshold = PS_SQR(NSIGMA_PEAK);
 
-    // move the old peaks array (if it exists) to oldPeaks
-    // XXX generically, we should be able to call this function an arbitrary number of times
+    // move the old peaks array (if it exists) to oldPeaks XXX generically, we should be able
+    // to call this function an arbitrary number of times the old peaks are saved so they can
+    // be freed later -- the have to be freed after psphotFindFootprints is called below, since
+    // they are also owned by the oldFootprints, which are in turn merged into the new
+    // footprints.  (what about the source->peak entry?)
+    
     assert (detections->oldPeaks == NULL);
     detections->oldPeaks = detections->peaks;
@@ -68,5 +102,5 @@
 	psFree (detections);
 	psError (PSPHOT_ERR_CONFIG, false, "failed on peak search");
-        return NULL;
+        return false;
     }
 
@@ -82,9 +116,5 @@
     psphotVisualShowFootprints (detections);
 
-    // save detections on the readout->analysis
-    if (!psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_DATA_PTR, "psphot detectinos", detections)) {
-	psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
-        return NULL;
-    }
+    psFree (detections);
 
     return true;
@@ -94,19 +124,2 @@
 // otherwise it only contains the new peaks.
 
-// for now, let's store the detections on the readout->analysis for each readout
-bool psphotFindDetections (pmConfig *config, const pmFPAview *view)
-{
-    bool status = true;
-
-    int num = psMetadataAddS32 (&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 (!psphotFindDetectionsReadout (config, view, "PSPHOT.INPUT", i)) {
-            psError (PSPHOT_ERR_CONFIG, false, "failed to find initial detections for PSPHOT.INPUT entry %d", i);
-	    return false;
-	}
-    }
-    return true;
-}
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotFitSourcesLinear.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotFitSourcesLinear.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotFitSourcesLinear.c	(revision 26688)
@@ -44,10 +44,13 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
     psAssert (sources, "missing sources?");
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotGuessModels.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotGuessModels.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotGuessModels.c	(revision 26688)
@@ -25,5 +25,5 @@
 }
 
-// construct an initial PSF model for each object
+// construct an initial PSF model for each object (new sources only)
 bool psphotGuessModelsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) {
 
@@ -39,5 +39,8 @@
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->newSources;
     psAssert (sources, "missing sources?");
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotImageQuality.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotImageQuality.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotImageQuality.c	(revision 26688)
@@ -31,5 +31,5 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
@@ -41,5 +41,8 @@
     }
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->newSources;
     psAssert (sources, "missing sources?");
 
@@ -123,6 +126,6 @@
 
     if (num == 0) {
-      psWarning("Unable to find sources from which to measure image quality");
-      return false;
+	psLogMsg ("psphot", PS_LOG_INFO, "no valid sources for image quality, skipping");
+	return true;
     }
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotMagnitudes.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotMagnitudes.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotMagnitudes.c	(revision 26688)
@@ -1,5 +1,26 @@
 # include "psphotInternal.h"
 
-bool psphotMagnitudes(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, const pmPSF *psf) {
+bool psphotMagnitudes (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    int num = psMetadataAddS32 (&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 (!psphotMagnitudesReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
+bool psphotMagnitudesReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) {
 
     bool status = false;
@@ -8,7 +29,24 @@
     psTimerStart ("psphot.mags");
 
-    // select the appropriate recipe information
-    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
-    assert (recipe);
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (readout, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
+    psAssert (sources, "missing sources?");
+
+    if (!sources->n) {
+	psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size");
+	return true;
+    }
+
+    pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
+    psAssert (psf, "missing psf?");
 
     // determine the number of allowed threads
@@ -64,5 +102,5 @@
 
             psArrayAdd(job->args, 1, cells->data[j]); // sources
-            psArrayAdd(job->args, 1, (pmPSF*)psf);    // Casting away const
+            psArrayAdd(job->args, 1, psf);
             psArrayAdd(job->args, 1, binning);
             psArrayAdd(job->args, 1, backModel);
@@ -179,43 +217,4 @@
 }
 
-# if (0)
-bool psphotMagnitudes_Unthreaded (int *nap, psArray *sources, pmPSF *psf, psImageBinning *binning, pmReadout *backModel, pmReadout *backStdev, pmSourcePhotometryMode photMode, psImageMaskType maskVal) {
-
-    bool status;
-    int Nap = 0;
-
-    for (int i = 0; i < sources->n; i++) {
-        pmSource *source = (pmSource *) sources->data[i];
-        status = pmSourceMagnitudes (source, psf, photMode, maskVal);
-        if (status && isfinite(source->apMag)) Nap ++;
-
-        if (backModel) {
-            psAssert (binning, "if backModel is defined, so should binning be");
-            source->sky = psImageUnbinPixel(source->peak->x, source->peak->y, backModel->image, binning);
-            if (isnan(source->sky) && false) {
-                psLogMsg ("psphot.magnitudes", PS_LOG_DETAIL, "error setting pmSource.sky");
-            }
-        } else {
-            source->sky = NAN;
-        }
-
-        if (backStdev) {
-            psAssert (binning, "if backStdev is defined, so should binning be");
-            source->skyErr = psImageUnbinPixel(source->peak->x, source->peak->y, backStdev->image, binning);
-            if (isnan(source->skyErr) && false) {
-                psLogMsg ("psphot.magnitudes", PS_LOG_DETAIL, "error setting pmSource.skyErr");
-            }
-        } else {
-            source->skyErr = NAN;
-        }
-    }
-
-    // change the value of a scalar on the array (wrap this and put it in psArray.h)
-    *nap = Nap;
-
-    return true;
-}
-# endif
-
 bool psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources) {
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotMergeSources.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotMergeSources.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotMergeSources.c	(revision 26688)
@@ -5,6 +5,55 @@
                          PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply for PSF sources
 
+// for now, let's store the detections on the readout->analysis for each readout
+bool psphotMergeSources (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    int num = psMetadataAddS32 (&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 (!psphotMergeSourcesReadout (config, view, "PSPHOT.INPUT", i)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed to merge sources for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
+// add newly selected sources to the existing list of sources
+bool psphotMergeSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) {
+
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (file, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *newSources = detections->newSources;
+    psAssert (newSources, "missing sources?");
+
+    if (!detections->allSources) {
+	detections->allSources = psArrayAllocEmpty(newSources->n);
+    }
+    psArray *allSources = detections->allSources;
+
+    for (int i = 0; i < newSources->n; i++) {
+        pmSource *source = newSources->data[i];
+        psArrayAdd (allSources, 100, source);
+    }
+
+    // XXX free detections->newSources?
+    return true;
+}
+
 // merge the externally supplied sources with the existing sources.  mark them as having
 // mode PM_SOURCE_MODE_EXTERNAL
+// XXX this function needs to be updated to work with the new context of pshot inputs
 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view, psArray *sources) {
 
@@ -71,15 +120,6 @@
 }
 
-// add newly selected sources to the existing list of sources
-bool psphotMergeSources (psArray *oldSources, psArray *newSources) {
-
-    for (int i = 0; i < newSources->n; i++) {
-        pmSource *source = newSources->data[i];
-        psArrayAdd (oldSources, 100, source);
-    }
-    return true;
-}
-
 // extract the input sources corresponding to this readout
+// XXX this function needs to be updated to work with the new context of pshot inputs
 psArray *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view) {
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotModelBackground.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotModelBackground.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotModelBackground.c	(revision 26688)
@@ -32,5 +32,5 @@
 // generate the median in NxN boxes, clipping heavily
 // linear interpolation to generate full-scale model
-bool psphotModelBackgroundReadout(psImage *model,  // Model image
+static bool psphotModelBackgroundReadout(psImage *model,  // Model image
 				  psImage *modelStdev, // Model stdev image
 				  psMetadata *analysis, // Analysis metadata for outputs
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotOutput.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotOutput.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotOutput.c	(revision 26688)
@@ -126,22 +126,4 @@
 }
 
-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 (readout->analysis, PS_LIST_TAIL, "PHOTCODE", PS_META_REPLACE, "photcode from FPA concepts", photcode);
-    psLogMsg ("psphot", 3, "PHOTCODE is %s", photcode);
-
-    psFree (photcode);
-    return true;
-}
-
 bool psphotAddPhotcode (pmConfig *config, const pmFPAview *view) {
 
@@ -158,4 +140,22 @@
 	}
     }
+    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 (readout->analysis, PS_LIST_TAIL, "PHOTCODE", PS_META_REPLACE, "photcode from FPA concepts", photcode);
+    psLogMsg ("psphot", 3, "PHOTCODE is %s", photcode);
+
+    psFree (photcode);
     return true;
 }
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotReadout.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotReadout.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotReadout.c	(revision 26688)
@@ -51,17 +51,18 @@
 
     // run a single-model test if desired (exits from here if test is run)
-    // XXX drop this and only keep the stand-alone program?
+    // XXX fix this in the new multi-input context (or drop this and only keep a stand-alone program)
     // psphotModelTest (config, view, recipe);
 
     // load the psf model, if suppled.  FWHM_X,FWHM_Y,etc are saved in the recipe
-    // XXX this needs to save the PSF on the chip->analysis or readout->analysis
-    if (!psphotLoadPSF (config, view, recipe)) {
-	// this only happens if we had a programming error in psphotLoadPSF
-        psError (PSPHOT_ERR_UNKNOWN, false, "error loading psf model");
-        return psphotReadoutCleanup (config, view);
-    }
+    // XXX the recipe is probably the wrong place to store those results...
+    // XXX this is using the wrong file... fix in the new context
+    // if (!psphotLoadPSF (config, view, recipe)) {
+    // 	// this only happens if we had a programming error in psphotLoadPSF
+    //     psError (PSPHOT_ERR_UNKNOWN, false, "error loading psf model");
+    //     return psphotReadoutCleanup (config, view);
+    // }
 	
     // find the detections (by peak and/or footprint) in the image.
-    if (!psphotFindDetections (config, view)) {
+    if (!psphotFindDetections (config, view)) { // pass 1
 	// this only happens if we had an error in psphotFindDetections
         psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
@@ -69,12 +70,6 @@
     }
 
-XXX: // need to handle or ignore this !!
-    if (!detections->peaks->n) {
-        psLogMsg ("psphot", 3, "unable to find detections in this image");
-        return psphotReadoutCleanup (config, view);
-    }
-
-    // construct sources and measure basic stats
-    if (!psphotSourceStats (config, view, true)) {
+    // construct sources and measure basic stats (saved on detections->newSources)
+    if (!psphotSourceStats (config, view, true)) { // pass 1
         psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources");
         return psphotReadoutCleanup (config, view);
@@ -84,5 +79,5 @@
     }
 
-    // find blended neighbors of very saturated stars
+    // find blended neighbors of very saturated stars (detections->newSources)
     if (!psphotDeblendSatstars (config, view)) {
         psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis");
@@ -90,5 +85,5 @@
     }
 
-    // mark blended peaks PS_SOURCE_BLEND
+    // mark blended peaks PS_SOURCE_BLEND (detections->newSources)
     if (!psphotBasicDeblend (config, view)) {
         psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis");
@@ -97,6 +92,6 @@
 
     // classify sources based on moments, brightness.  if a PSF model has been loaded, the PSF
-    // clump defined for it is used not measured
-    if (!psphotRoughClass (config, view)) {
+    // clump defined for it is used not measured (detections->newSources)
+    if (!psphotRoughClass (config, view)) { // pass 1
         psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications");
         return psphotReadoutCleanup (config, view);
@@ -106,7 +101,7 @@
     }
 
-    // if we were not supplied a PSF model, determine the IQ stats here
-    if (!psphotImageQuality (config, view)) {
-        psLogMsg("psphot", 3, "failed to measure image quality");
+    // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources)
+    if (!psphotImageQuality (config, view)) { // pass 1
+        psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality");
         return psphotReadoutCleanup(config, view);
     }
@@ -114,5 +109,5 @@
     // use bright stellar objects to measure PSF if we were supplied a PSF for any input file,
     // this step is skipped
-    if (!psphotChoosePSF (config, view)) {
+    if (!psphotChoosePSF (config, view)) { // pass 1
 	psLogMsg ("psphot", 3, "failure to construct a psf model");
 	return psphotReadoutCleanup (config, view);
@@ -123,15 +118,20 @@
 
     // include externally-supplied sources
-    // XXX hmm...
-    psphotLoadExtSources (config, view, sources);
-
-    // construct an initial model for each object, set the radius to fitRadius, set circular fit mask
-    psphotGuessModels (config, view);
+    // XXX fix this in the new multi-input context
+    // psphotLoadExtSources (config, view, sources); // pass 1
+
+    // construct an initial model for each object, set the radius to fitRadius, set circular
+    // fit mask (detections->newSources)
+    psphotGuessModels (config, view); // pass 1
+
+    // merge the newly selected sources into the existing list
+    // NOTE: merge OLD and NEW
+    psphotMergeSources (config, view); FIX:
 
     // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)
-    psphotFitSourcesLinear (config, view, FALSE);
-
-    // identify CRs and extended sources
-    psphotSourceSize (config, view);
+    psphotFitSourcesLinear (config, view, false); // pass 1 (detections->allSources)
+
+    // identify CRs and extended sources (only unmeasured sources are measured)
+    psphotSourceSize (config, view, true); // pass 1 (detections->allSources)
     if (!strcasecmp (breakPt, "ENSEMBLE")) {
         goto finish;
@@ -140,35 +140,36 @@
     // non-linear PSF and EXT fit to brighter sources
     // replace model flux, adjust mask as needed, fit, subtract the models (full stamp)
-    psphotBlendFit (config, view);
+    psphotBlendFit (config, view); // pass 1 (detections->allSources)
 
     // replace all sources
-    psphotReplaceAllSources (config, view);
+    psphotReplaceAllSources (config, view); // pass 1 (detections->allSources)
 
     // linear fit to include all sources (subtract again)
-    psphotFitSourcesLinear (config, view, TRUE);
+    // NOTE : apply to ALL sources (extended + psf)
+    psphotFitSourcesLinear (config, view, true); // pass 2 (detections->allSources)
 
     // if we only do one pass, skip to extended source analysis
-    if (!strcasecmp (breakPt, "PASS1")) {
-        goto pass1finish;
-    }
-    // NOTE: possibly re-measure background model here with objects subtracted
+    if (!strcasecmp (breakPt, "PASS1")) goto pass1finish;
+
+    // NOTE: possibly re-measure background model here with objects subtracted / or masked
 
     // add noise for subtracted objects
-    psphotAddNoise (config, view);
-
-    // find fainter sources (pass 2)
-    // XXX need to distinguish old from new sources
-    psphotFindDetections (config, view);
+    psphotAddNoise (config, view); // pass 1 (detections->allSources)
+
+    // find fainter sources
+    // NOTE: finds new peaks and new footprints, OLD and FULL set are saved on detections
+    psphotFindDetections (config, view); // pass 2 (detections->peaks, detections->footprints)
 
     // remove noise for subtracted objects (ie, return to normal noise level)
-    // XXX this needs to operate only on the OLD sources
-    psphotSubNoise (config, view);
+    // NOTE: this needs to operate only on the OLD sources
+    psphotSubNoise (config, view); // pass 1 (detections->allSources)
 
     // define new sources based on only the new peaks
-    // XXX need to distinguish old from new sources
-    psphotSourceStats (config, view, false);
+    // NOTE: new sources are saved on detections->newSources
+    psphotSourceStats (config, view, false); // pass 2 (detections->newSources)
 
     // set source type
-    if (!psphotRoughClass (config, view)) {
+    // NOTE: apply only to detections->newSources
+    if (!psphotRoughClass (config, view)) { // pass 2 (detections->newSources)
         psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
         return psphotReadoutCleanup (config, view);
@@ -176,25 +177,26 @@
 
     // create full input models, set the radius to fitRadius, set circular fit mask
-    // XXX need to distinguish old from new sources
-    psphotGuessModels (config, view);
+    // NOTE: apply only to detections->newSources
+    psphotGuessModels (config, view); // pass 2 (detections->newSources)
 
     // replace all sources so fit below applies to all at once
-    psphotReplaceAllSources (config, view);
+    // NOTE: apply only to OLD sources (which have been subtracted)
+    psphotReplaceAllSources (config, view); // pass 2
 
     // merge the newly selected sources into the existing list
-    // XXX old vs new????
-FIX:    psphotMergeSources (sources, newSources);
-    psFree (newSources);
-
-    // linear fit to all sources
-    psphotFitSourcesLinear (config, view, TRUE);
+    // NOTE: merge OLD and NEW
+    psphotMergeSources (config, view); FIX: // (detections->newSources + detections->allSources -> detections->allSources)
+
+    // NOTE: apply to ALL sources
+    psphotFitSourcesLinear (config, view, true); // pass 3 (detections->allSources)
 
 pass1finish:
 
     // measure source size for the remaining sources
-    psphotSourceSize (config, view);
-
-FIX:    psphotExtendedSourceAnalysis (readout, sources, recipe);
-FIX:    psphotExtendedSourceFits (readout, sources, recipe);
+    // NOTE: applies only to NEW (unmeasured) sources
+    psphotSourceSize (config, view, false); // pass 2 (detections->allSources)
+
+    psphotExtendedSourceAnalysis (config, view); // pass 1 (detections->allSources)
+    psphotExtendedSourceFits (config, view); // pass 1 (detections->allSources)
 
 finish:
@@ -204,5 +206,5 @@
 
     // measure aperture photometry corrections
-FIX:    if (!psphotApResid (config, readout, sources, psf)) {
+    if (!psphotApResid (config, view)) { // pass 1 (detections->allSources)
         psLogMsg ("psphot", 3, "failed on psphotApResid");
         return psphotReadoutCleanup (config, view);
@@ -210,7 +212,7 @@
 
     // calculate source magnitudes
-FIX:    psphotMagnitudes(config, readout, view, sources, psf);
-
-FIX:    if (!psphotEfficiency(config, readout, view, psf, recipe, sources)) {
+    psphotMagnitudes(config, view); // pass 1 (detections->allSources)
+
+    if (!psphotEfficiency(config, view)) { // pass 1
         psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources");
         psErrorClear();
@@ -221,8 +223,8 @@
 
     // replace background in residual image
-FIX:    psphotSkyReplace (config, view);
+    psphotSkyReplace (config, view); // pass 1
 
     // drop the references to the image pixels held by each source
-FIX:    psphotSourceFreePixels (sources);
+    psphotSourceFreePixels (config, view); // pass 1
 
     // create the exported-metadata and free local data
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotReadoutCleanup.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotReadoutCleanup.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotReadoutCleanup.c	(revision 26688)
@@ -51,8 +51,7 @@
 
     // when psphotReadoutCleanup is called, these are not necessarily defined
-    psArray *sources         = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
-    pmPSF *psf               = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
+    pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
     pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
-
+    psArray *sources = detections->allSources;
     // XXX where do we free these, in here (psMetadataRemove?)
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotReplaceUnfit.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotReplaceUnfit.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotReplaceUnfit.c	(revision 26688)
@@ -53,10 +53,13 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
     psAssert (sources, "missing sources?");
 
@@ -99,42 +102,2 @@
     return true;
 }
-
-# if (0)
-// add source, if the source has been subtracted; do not modify state
-bool psphotAddWithTest (pmSource *source, bool useState, psImageMaskType maskVal) {
-
-    // what is current state? (true : add; false : sub)
-    bool state = !(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
-    if (state && useState) return true;
-
-    pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-    return true;
-}
-
-// sub source, if the source has been added; do not modify state
-bool psphotSubWithTest (pmSource *source, bool useState, psImageMaskType maskVal) {
-
-    // what is current state? (true : sub; false : add)
-    bool state = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
-    if (state && useState) return true;
-
-    pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-    return true;
-}
-
-// add or sub source to match recorded state: supply current state as true (add) or false (sub)
-bool psphotSetState (pmSource *source, bool curState, psImageMaskType maskVal) {
-
-    // what is desired state? (true : add; false : sub)
-    bool newState = !(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
-    if (curState == newState) return true;
-
-    if (curState && !newState) {
-        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-    }
-    if (newState && !curState) {
-        pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-    }
-    return true;
-}
-# endif
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotRoughClass.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotRoughClass.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotRoughClass.c	(revision 26688)
@@ -37,5 +37,5 @@
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
-    psAssert (readout, "missing file?");
+    psAssert (file, "missing file?");
 
     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
@@ -48,5 +48,8 @@
     }
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->newSources;
     psAssert (sources, "missing sources?");
 
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotSkyReplace.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotSkyReplace.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotSkyReplace.c	(revision 26688)
@@ -1,13 +1,33 @@
 # include "psphotInternal.h"
+
+bool psphotSkyReplace (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
+
+    int num = psMetadataAddS32 (&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 (!psphotReadout (config, view, "PSPHOT.INPUT", i)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
 
 // XXX make this an option?
 // in order to  successfully replace the sky, we must define a corresponding file...
-bool psphotSkyReplace (pmConfig *config, const pmFPAview *view) {
+bool psphotSkyReplaceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) {
 
     psTimerStart ("psphot.skyreplace");
 
     // find the currently selected readout
-    pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");
-    if (readout == NULL) psAbort("input not defined");
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (readout, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
 
     // select background pixels, from output background file, or create
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotSourceFreePixels.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotSourceFreePixels.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotSourceFreePixels.c	(revision 26688)
@@ -1,7 +1,35 @@
 # include "psphotInternal.h"
 
-void psphotSourceFreePixels (psArray *sources) {
+bool psphotSourceFreePixels (pmConfig *config, const pmFPAview *view)
+{
+    bool status = true;
 
-    if (!sources) return;
+    int num = psMetadataAddS32 (&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 (!psphotSourceFreePixelsReadout (config, view, "PSPHOT.INPUT", i)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
+bool psphotSourceFreePixelsReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index) {
+
+    // find the currently selected readout
+    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
+    psAssert (readout, "missing file?");
+
+    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+    psAssert (readout, "missing readout?");
+
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
+    psAssert (sources, "missing sources?");
 
     for (int i = 0; i < sources->n; i++) {
@@ -9,4 +37,4 @@
 	pmSourceFreePixels (source);
     }
-    return;
+    return true;
 }
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotSourceSize.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotSourceSize.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotSourceSize.c	(revision 26688)
@@ -16,5 +16,4 @@
 
 // local functions:
-bool psphotSourceSizeReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index);
 bool psphotSourceSizePSF (psphotSourceSizeOptions *options, psArray *sources, pmPSF *psf);
 bool psphotSourceClass (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options);
@@ -31,5 +30,5 @@
 
 // for now, let's store the detections on the readout->analysis for each readout
-bool psphotSourceSize (pmConfig *config, const pmFPAview *view)
+bool psphotSourceSize (pmConfig *config, const pmFPAview *view, bool getPSFsize)
 {
     bool status = true;
@@ -44,5 +43,5 @@
     // loop over the available readouts
     for (int i = 0; i < num; i++) {
-	if (!psphotSourceSizeReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
+	if (!psphotSourceSizeReadout (config, view, "PSPHOT.INPUT", i, recipe, getPSFsize)) {
             psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i);
 	    return false;
@@ -52,6 +51,6 @@
 }
 
-// XXX use an internal flag to mark sources which have already been measured
-bool psphotSourceSizeReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe)
+// this function use an internal flag to mark sources which have already been measured
+bool psphotSourceSizeReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool getPSFsize)
 {
     bool status;
@@ -67,5 +66,8 @@
     psAssert (readout, "missing readout?");
 
-    psArray *sources = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.SOURCES");
+    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+    psAssert (detections, "missing detections?");
+
+    psArray *sources = detections->allSources;
     psAssert (sources, "missing sources?");
 
@@ -116,9 +118,15 @@
     // XXX move this to the code that generates the PSF?
     // XXX store the results on pmPSF?
-    psphotSourceSizePSF (&options, sources, psf);
+
+    // XXX this should only be done on the first pass (ie, if we have newSources or allSources?)
+    if (getPSFsize) {
+	psphotSourceSizePSF (&options, sources, psf);
+    }
 
     // classify the sources based on ApResid and Moments (extended sources)
+    // NOTE: only sources not already measured !(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED)
     psphotSourceClass(readout, sources, recipe, psf, &options);
 
+    // NOTE: only sources not already measured !(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED)
     psphotSourceSizeCR (readout, sources, &options);
 
@@ -376,4 +384,10 @@
     for (int i = 0; i < sources->n; i++) {
         pmSource *source = sources->data[i];
+
+        // skip source if it was already measured
+        if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) {
+            psTrace("psphot", 7, "Not calculating source size since it has already been measured\n");
+            continue;
+        }
 
         // Integer position of peak
Index: /branches/eam_branches/psphot.stack.20100120/src/psphotSourceStats.c
===================================================================
--- /branches/eam_branches/psphot.stack.20100120/src/psphotSourceStats.c	(revision 26687)
+++ /branches/eam_branches/psphot.stack.20100120/src/psphotSourceStats.c	(revision 26688)
@@ -1,5 +1,6 @@
 # include "psphotInternal.h"
 
-// convert detections to sources and measure their basic properties (moments, local sky, sky variance)
+// convert detections to sources and measure their basic properties (moments, local sky, sky
+// variance) Note: this function only generates sources for the new peaks (peak->assigned)
 bool psphotSourceStats (pmConfig *config, const pmFPAview *view, bool setWindow)
 {
@@ -39,4 +40,5 @@
     pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     psAssert (detections, "missing detections?");
+    psAssert (!detections->newSources, "new sources already defined?");
 
     // determine the number of allowed threads
@@ -67,11 +69,6 @@
     // if there are no peaks, we save the empty source array and return
     if (!peaks->n) {
-	// save sources on the readout->analysis
-	if (!psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY, "psphot sources", sources)) {
-	    psError (PSPHOT_ERR_UNKNOWN, false, "problem saving sources on readout");
-	    psFree(sources);
-	    return false;
-	}
-	psFree(sources);
+	// save the new sources on the detection structure:
+	detections->newSources = sources;
 	return true;
     }
@@ -103,11 +100,5 @@
         psLogMsg ("psphot", PS_LOG_INFO, "break point PEAKS, skipping MOMENTS\n");
         psphotVisualShowMoments (sources);
-	// save sources on the readout->analysis
-	if (!psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY, "psphot sources", sources)) {
-	    psError (PSPHOT_ERR_UNKNOWN, false, "problem saving sources on readout");
-	    psFree(sources);
-	    return false;
-	}
-	psFree(sources);
+	detections->newSources = sources;
         return true;
     }
@@ -187,11 +178,6 @@
     psphotVisualShowMoments (sources);
 
-    // save sources on the readout->analysis
-    if (!psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY, "psphot sources", sources)) {
-	psError (PSPHOT_ERR_UNKNOWN, false, "problem saving sources on readout");
-	psFree(sources);
-        return false;
-    }
-    psFree(sources);
+    // save the new sources on the detection structure:
+    detections->newSources = sources;
     return true;
 }
@@ -216,10 +202,10 @@
     // determine properties (sky, moments) of initial sources
     float OUTER    = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
-    if (!status) return NULL;
+    if (!status) return false;
 
     OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius
 
     char *breakPt  = psMetadataLookupStr (&status, recipe, "BREAK_POINT");
-    if (!status) return NULL;
+    if (!status) return false;
 
     for (int i = 0; i < sources->n; i++) {
@@ -509,5 +495,4 @@
 }
 
-
 // if we use the footprints, the output peaks list contains both old and new peaks,
 // otherwise it only contains the new peaks.
