Index: /branches/pap/psphot/src/psphotFake.c
===================================================================
--- /branches/pap/psphot/src/psphotFake.c	(revision 24013)
+++ /branches/pap/psphot/src/psphotFake.c	(revision 24013)
@@ -0,0 +1,113 @@
+# include "psphotInternal.h"
+
+#define TESTING
+
+
+#ifdef TESTING
+#define MIN_FLUX 0.1                    // Minimum flux for faint sources
+#endif
+
+
+// *** in this section, perform the photometry for fake sources ***
+bool psphotFake(pmConfig *config, pmReadout *readout, const pmPSF *psf,
+                const psMetadata *recipe, const psArray *realSources)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+    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("psphotFake");
+
+    // Generate array of fake sources and define the pixels with pmSourceDefinePixels
+    psArray *fakeOrig = psphotFakeGenerate(config, readout, recipe);
+
+    psArray *fakeMeasured = psArrayAlloc(fakeOrig->n); // Measured values for the sources in fakeOrig
+    for (int i = 0; i < fakeOrig->n; i++) {
+        fakeMeasured->data[i] = pmSourceCopy(fakeOrig->data[i]);
+    }
+
+    int numCols = readout->image->numCols, numRows = readout->image->numRows; // Size of image
+
+    pmReadout *fakeRO = pmReadoutAlloc(NULL); // Readout with fake sources
+
+    if (!pmReadoutFakeFromSources(fakeRO, numCols, numRows, fakeOrig, NULL, NULL,
+                                  psf, MIN_FLUX, 0, false, false)) {
+        psError(psErrorCodeLast(), false, "Unable to generate fake readout");
+        psFree(fakeRO);
+        psFree(fakeMeasured);
+        psFree(fakeOrig);
+        return false;
+    }
+
+
+bool pmReadoutFakeFromSources(pmReadout *readout, ///< Output readout, or NULL
+                              int numCols, int numRows, ///< Dimension of image
+                              const psArray *sources, ///< Array of pmSource
+                              const psVector *xOffset, ///< x offsets for sources (source -> img), or NULL
+                              const psVector *yOffset, ///< y offsets for sources (source -> img), or NULL
+                              const pmPSF *psf, ///< PSF for sources
+                              float minFlux, ///< Minimum flux to bother about; for setting source radius
+                              int radius, ///< Fixed radius for sources
+                              bool circularise, ///< Circularise PSF model?
+                              bool normalise ///< Normalise the peak value?
+    );
+
+
+
+
+    // remove all sources
+    psphotRemoveAllSources(realSources, recipe);
+
+    // add noise for real (subtracted) objects
+    psphotAddNoise (readout, realSources, recipe);
+
+    // XXX fake sources should measure peak->x,y, force sources should not
+    psImageMaskType maskVal = 0xff;
+    psImage *significance = psphotSignificanceImage(readout, recipe, 1, maskVal);
+    ppSimDetections (significance, recipe, fakeSources);
+    psFree (significance);
+
+    // remove noise for subtracted objects (ie, return to normal noise level)
+    psphotSubNoise (readout, realSources, recipe);
+
+    // replace all sources
+    psphotReplaceAllSources (realSources, recipe);
+
+    // construct an initial model for each object
+    psphotGuessModels (config, readout, realSources, psf);
+    psphotGuessModels (config, readout, fakeSources, psf);
+
+    // linear fit to real + fake sources
+    psArray *sources = ppSimMergeSources (realSources, fakeSources);
+    psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE); // XXX option to NOT subtract
+    psphotReplaceAllSources (sources, recipe);
+    psFree (sources); // only frees the merged references
+
+    // calculate source magnitudes (for which set??)
+    psphotMagnitudes(config, readout, view, fakeSources, psf);
+
+    // drop the references to the image pixels held by each source
+    psphotSourceFreePixels (realSources);
+    psphotSourceFreePixels (fakeSources);
+
+    // create the exported-metadata and free local data
+    // XXX this places the sources on readout->analysis as PSPHOT.SOURCES.  modify?
+    // (or don't supply the sources, and do this with a different function)
+    psphotReadoutCleanup(config, readout, recipe, NULL, psf, NULL);
+
+    pmCell    *fakeCell    = pmFPAfileThisCell (config->files, view, "PPSIM.FAKE.SOURCES"); psAssert (fakeCell, "no cell?");
+    pmChip    *fakeChip    = pmFPAfileThisChip (config->files, view, "PPSIM.FAKE.SOURCES"); psAssert (fakeChip, "no chip?");
+    pmReadout *fakeReadout = pmFPAfileThisReadout (config->files, view, "PPSIM.FAKE.SOURCES");
+    if (!fakeReadout) {
+        fakeReadout = pmReadoutAlloc (fakeCell);
+        psFree (fakeReadout); // there is a copy on 'cell' as well
+    }
+    psAssert (fakeReadout, "no fakeReadout?");
+    pmChipSetDataStatus (fakeChip, true);
+    psMetadataAddArray (fakeReadout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_META_REPLACE, "fake photometry ", fakeSources);
+
+    return true;
+}
