Index: trunk/ppViz/src/ppVizPSF/ppVizPSF.h
===================================================================
--- trunk/ppViz/src/ppVizPSF/ppVizPSF.h	(revision 27666)
+++ trunk/ppViz/src/ppVizPSF/ppVizPSF.h	(revision 27667)
@@ -11,5 +11,5 @@
     psString psfName;                   // Filename with PSF
     psString sourcesName;               // Filename with sources
-    int fakeNum;		        // Number of fake sources
+    int fakeNum;                        // Number of fake sources
     float fakeMag;                      // Magnitude of fake sources
     psString outRoot;                   // Output root name
@@ -17,4 +17,5 @@
     int size;                           // Size of PSF image
     float x, y;                         // Position of fake source
+    psArray *input;                     // Input positions and magnitudes
     pmConfig *config;                   // Configuration
 } ppVizPSFData;
Index: trunk/ppViz/src/ppVizPSF/ppVizPSFArguments.c
===================================================================
--- trunk/ppViz/src/ppVizPSF/ppVizPSFArguments.c	(revision 27666)
+++ trunk/ppViz/src/ppVizPSF/ppVizPSFArguments.c	(revision 27667)
@@ -50,4 +50,5 @@
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-psf", 0, "Filename of PSF", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-sources", 0, "Filename of CMF sources", NULL);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-input", 0, "Filename with x,y,mag", NULL);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-fake-num", 0, "Number of fake sources", 0);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-fake-mag", 0, "Magnitude of fake sources", NAN);
@@ -68,4 +69,13 @@
     psMetadataAddStr(data->config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "Output root name", data->outRoot);
 
+    const char *inputName = psMetadataLookupStr(NULL, arguments, "-input"); // Name of input file
+    if (inputName) {
+        data->input = psVectorsReadFromFile(inputName, "%f %f %f");
+        if (!data->input) {
+            psError(psErrorCodeLast(), false, "Unable to read input file %s", inputName);
+            return false;
+        }
+    }
+
     psTrace("ppVizPSF", 1, "Done reading command-line arguments\n");
     psFree(arguments);
Index: trunk/ppViz/src/ppVizPSF/ppVizPSFData.c
===================================================================
--- trunk/ppViz/src/ppVizPSF/ppVizPSFData.c	(revision 27666)
+++ trunk/ppViz/src/ppVizPSF/ppVizPSFData.c	(revision 27667)
@@ -16,4 +16,5 @@
     psFree(data->sourcesName);
     psFree(data->outRoot);
+    psFree(data->input);
     psFree(data->config);
     return;
@@ -36,4 +37,5 @@
     data->x = NAN;
     data->y = NAN;
+    data->input = NULL;
 
     return data;
Index: trunk/ppViz/src/ppVizPSF/ppVizPSFLoop.c
===================================================================
--- trunk/ppViz/src/ppVizPSF/ppVizPSFLoop.c	(revision 27666)
+++ trunk/ppViz/src/ppVizPSF/ppVizPSFLoop.c	(revision 27667)
@@ -75,5 +75,5 @@
                 psVector *xOffset = NULL, *yOffset = NULL; // Offset from source to true position
 
-                if (sources || (data->fakeNum > 0 && isfinite(data->fakeMag))) {
+                if (sources || data->input || (data->fakeNum > 0 && isfinite(data->fakeMag))) {
                     numCols = psf->fieldNx;
                     numRows = psf->fieldNy;
@@ -82,6 +82,10 @@
                 if (sources) {
                     psMemIncrRefCounter(sources);
-                    psLogMsg("ppVizPSF", PS_LOG_INFO, "Using %ld input sources", sources->n);
-                }
+                    psLogMsg("ppVizPSF", PS_LOG_INFO, "Using %ld input sources from CMF file", sources->n);
+                } else if (data->input) {
+                    psVector *x = data->input->data[0]; // x coordinates
+                    psLogMsg("ppVizPSF", PS_LOG_INFO, "Using %ld input sources from text file", x->n);
+                }
+
                 if (data->fakeNum > 0 && isfinite(data->fakeMag)) {
                     long numOld = 0; // Old number of sources
@@ -113,5 +117,5 @@
                     }
                 }
-                if (!sources) {
+                if (!sources && !data->input) {
                     // Generate fake image with only a single realisation of the PSF
                     sources = psArrayAlloc(1);
@@ -137,8 +141,4 @@
                     psRegion *trimsec = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC");
                     *trimsec = psRegionSet(0, numCols, 0, numRows);
-
-                    // We have trouble with PSF residuals in this case, so don't use them
-                    psFree(psf->residuals);
-                    psf->residuals = NULL;
                 }
 
@@ -148,8 +148,23 @@
                 }
 
-                if (!pmReadoutFakeFromSources(readout, numCols, numRows, sources, 0, xOffset, yOffset, psf,
-                                              data->minFlux, 0, false, true)) {
-                    psError(PS_ERR_UNKNOWN, false, "Unable to generate fake readout.");
-                    return false;
+                // We have trouble with PSF residuals, so don't use them
+                psFree(psf->residuals);
+                psf->residuals = NULL;
+
+                if (sources) {
+                    if (!pmReadoutFakeFromSources(readout, numCols, numRows, sources, 0, xOffset, yOffset,
+                                                  psf, data->minFlux, 0, false, true)) {
+                        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake readout.");
+                        return false;
+                    }
+                } else if (data->input) {
+                    psVector *x = data->input->data[0]; // x coordinates
+                    psVector *y = data->input->data[1]; // y coordinates
+                    psVector *mag = data->input->data[2]; // Magnitudes
+                    if (!pmReadoutFakeFromVectors(readout, numCols, numRows, x, y, mag, xOffset, yOffset,
+                                                  psf, data->minFlux, 0, false, true)) {
+                        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake readout.");
+                        return false;
+                    }
                 }
 
