Index: trunk/psphot/src/Makefile.am
===================================================================
--- trunk/psphot/src/Makefile.am	(revision 21183)
+++ trunk/psphot/src/Makefile.am	(revision 21248)
@@ -14,5 +14,4 @@
 	psphotImageLoop.c	\
 	psphotMosaicChip.c	\
-	psphotSetMaskBits.c	\
 	psphotParseCamera.c
 
@@ -29,4 +28,6 @@
 	psphotReadout.c		       \
 	psphotReadoutFindPSF.c	       \
+	psphotReadoutKnownSources.c    \
+	psphotReadoutMinimal.c	       \
 	psphotModelBackground.c	       \
 	psphotSubtractBackground.c     \
@@ -46,4 +47,5 @@
 	psphotMakeGrowthCurve.c	       \
 	psphotMagnitudes.c	       \
+	psphotSetMaskBits.c	       \
 	psphotSkyReplace.c	       \
 	psphotEvalPSF.c		       \
Index: trunk/psphot/src/psphotReadoutKnownSources.c
===================================================================
--- trunk/psphot/src/psphotReadoutKnownSources.c	(revision 21248)
+++ trunk/psphot/src/psphotReadoutKnownSources.c	(revision 21248)
@@ -0,0 +1,85 @@
+# include "psphotInternal.h"
+
+// in this psphotReadout-variant, we are only measuring the photometry for known sources,
+// using a PSF generated from this observation those sources
+bool psphotReadoutKnownSources(pmConfig *config, const pmFPAview *view, psArray *inSources) {
+
+    psTimerStart ("psphotReadout");
+
+    // select the current recipe
+    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
+    if (!recipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);
+        return false;
+    }
+
+    // find the currently selected readout
+    pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");
+    PS_ASSERT_PTR_NON_NULL (readout, false);
+
+    // Generate the mask and weight images, including the user-defined analysis region of interest
+    psphotSetMaskAndWeight (config, readout, recipe);
+
+    // display the image, weight, mask (ch 1,2,3)
+    psphotVisualShowImage (readout);
+
+    // Note that in this implementation, we do NOT model the background and we do not
+    // attempt to detect the sources in the image
+
+    // include externally-supplied sources (supplied as PSPHOT.INPUT.CMF)
+    pmDetections *detections = psphotDetectionsFromSources (config, inSources);
+    if (!detections || !detections->peaks) {
+        psError(PSPHOT_ERR_ARGUMENTS, true, "Can't find PSF stars");
+        return psphotReadoutCleanup(config, readout, recipe, detections, NULL, NULL);
+    }
+
+    // construct sources and measure basic stats
+    psArray *sources = psphotSourceStats (config, readout, detections);
+    if (!sources) return false;
+
+    // peak flux is wrong : set based on previous image
+    // use the peak measured in the moments analysis:
+    for (int i = 0; i < sources->n; i++) {
+	pmSource *source = sources->data[i];
+	source->peak->flux = source->moments->Peak;
+    }
+    
+    // classify sources based on moments, brightness (psf is not known)
+    if (!psphotRoughClass (readout, sources, recipe, false)) {
+        psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
+        return psphotReadoutCleanup (config, readout, recipe, detections, NULL, sources);
+    }
+
+    pmPSF *psf = psphotChoosePSF (readout, sources, recipe);
+    if (!psf) {
+	psLogMsg ("psphot", 3, "failure to construct a psf model");
+	return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
+    }
+    psphotVisualShowPSFModel (readout, psf);
+
+    // construct an initial model for each object
+    psphotGuessModels (config, readout, sources, psf);
+
+    // linear PSF fit to source peaks
+    psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE);
+
+    // We have to place these visualizations here because the models are not realized until
+    // psphotGuessModels or fitted until psphotFitSourcesLinear.
+    psphotVisualShowPSFStars (recipe, psf, sources);
+    psphotVisualShowSatStars (recipe, psf, sources);
+
+    // measure aperture photometry corrections
+    if (!psphotApResid (config, readout, sources, psf)) {
+        psLogMsg ("psphot", 3, "failed on psphotApResid");
+        return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
+    }
+
+    // calculate source magnitudes
+    psphotMagnitudes(config, readout, view, sources, psf);
+
+    // drop the references to the image pixels held by each source
+    psphotSourceFreePixels (sources);
+
+    // create the exported-metadata and free local data
+    return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
+}
Index: trunk/psphot/src/psphotReadoutMinimal.c
===================================================================
--- trunk/psphot/src/psphotReadoutMinimal.c	(revision 21248)
+++ trunk/psphot/src/psphotReadoutMinimal.c	(revision 21248)
@@ -0,0 +1,97 @@
+# include "psphotInternal.h"
+
+// this badly-named function performs photometry assuming (a) a supplied PSF, (b)
+// background subtraction, (c) linear psf-model fits only.  it is currently only being
+// used by ppSub.
+
+// NOTE: ppSub needs to perform extended source analysis for comets and trails.  
+
+bool psphotReadoutMinimal(pmConfig *config, const pmFPAview *view) {
+
+    // measure the total elapsed time in psphotReadout.  XXX the current threading plan
+    // for psphot envisions threading within psphotReadout, not multiple threads calling
+    // the same psphotReadout.  In the current plan, this dtime is the elapsed time used
+    // jointly by the multiple threads, not the total time used by all threads.
+    psTimerStart ("psphotReadout");
+
+    // select the current recipe
+    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
+    if (!recipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);
+        return false;
+    }
+
+    // find the currently selected readout
+    pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");
+    PS_ASSERT_PTR_NON_NULL (readout, false);
+
+    // Generate the mask and weight images, including the user-defined analysis region of interest
+    psphotSetMaskAndWeight (config, readout, recipe);
+
+    // display the image, weight, mask (ch 1,2,3)
+    psphotVisualShowImage (readout);
+
+    // load the psf model, if suppled.  FWHM_X,FWHM_Y,etc are saved in the recipe
+    pmPSF *psf = psphotLoadPSF (config, view, recipe);
+    if (!psf) {
+      psError (PSPHOT_ERR_CONFIG, false, "missing psf model");
+      return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);
+    }
+
+    // find the detections (by peak and/or footprint) in the image.
+    pmDetections *detections = psphotFindDetections (NULL, readout, recipe);
+    if (!detections) {
+        psLogMsg ("psphot", 3, "unable to find detections in this image");
+        return psphotReadoutCleanup (config, readout, recipe, detections, psf, NULL);
+    }
+
+    // construct sources and measure basic stats
+    psArray *sources = psphotSourceStats (config, readout, detections);
+    if (!sources) return false;
+
+    // find blended neighbors of very saturated stars
+    // XXX merge this with Basic Deblend?
+    psphotDeblendSatstars (sources, recipe);
+
+    // mark blended peaks PS_SOURCE_BLEND
+    if (!psphotBasicDeblend (sources, recipe)) {
+        psLogMsg ("psphot", 3, "failed on deblend analysis");
+        return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
+    }
+
+    // classify sources based on moments, brightness (use supplied psf shape parameters)
+    if (!psphotRoughClass (readout, sources, recipe, true)) {
+        psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
+        return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
+    }
+
+    // construct an initial model for each object
+    psphotGuessModels (config, readout, sources, psf);
+
+    // linear PSF fit to source peaks
+    psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE);
+
+    // We have to place these visualizations here because the models are not realized until
+    // psphotGuessModels or fitted until psphotFitSourcesLinear.
+    psphotVisualShowPSFStars (recipe, psf, sources);
+    psphotVisualShowSatStars (recipe, psf, sources);
+
+// XXX eventually, add the extended source fits here
+# if (0) 
+    // measure source size for the remaining sources
+    psphotSourceSize (config, readout, sources, recipe, 0);
+
+    psphotExtendedSourceAnalysis (readout, sources, recipe);
+
+    psphotExtendedSourceFits (readout, sources, recipe);
+# endif
+
+    // calculate source magnitudes
+    psphotMagnitudes(config, readout, view, sources, psf);
+
+    // drop the references to the image pixels held by each source
+    psphotSourceFreePixels (sources);
+
+    // create the exported-metadata and free local data
+    return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
+}
