Index: trunk/ppImage/src/Makefile.am
===================================================================
--- trunk/ppImage/src/Makefile.am	(revision 7508)
+++ trunk/ppImage/src/Makefile.am	(revision 7522)
@@ -10,13 +10,14 @@
 ppImage_SOURCES = \
 	ppImage.c \
-	ppImageConfig.c \
+	ppImageArguments.c \
+	ppImageParseCamera.c \
+	ppImageLoop.c \
+	ppImageCleanup.c \
 	ppImageOptions.c \
-	ppImageParseDetrend.c \
-	ppImageLoop.c \
 	ppImageDetrendReadout.c \
 	ppImageDetrendBias.c \
 	ppImageDetrendNonLinear.c \
 	ppImageRebinReadout.c \
-	ppImagePhot.c \
+	ppImagePhotom.c \
 	ppMem.c
 
Index: trunk/ppImage/src/ppImage.c
===================================================================
--- trunk/ppImage/src/ppImage.c	(revision 7508)
+++ trunk/ppImage/src/ppImage.c	(revision 7522)
@@ -9,24 +9,25 @@
     // Determine camera, format from header if not already defined
     // Construct camera in preparation for reading
-    pmConfig *config = ppImageConfig(&argc, argv);
+    pmConfig *config = ppImageArguments(&argc, argv);
+    if (config == NULL) {
+	psErrorStackPrint(stderr, "");
+	exit(1);
+    }
 
-    // Set various tasks (define optional operations)
-    ppImageOptions *options = ppImageOptionsParse(config);
-
+    // define recipe options
     // define the active I/O files
-    ppImageParseDetrend(options, config);
+    ppImageOptions *options = ppImageParseCamera(config);
+    if (options == NULL) {
+	psErrorStackPrint(stderr, "");
+	exit(1);
+    }
 
     // Image Arithmetic Loop
-    ppImageLoop(options, config);
+    ppImageLoop(config, options);
+
+    psLogMsg ("psphot", 3, "complete psphot run: %f sec\n", psTimerMark ("complete"));
 
     // Cleaning up
-    psFree(options);
-    psFree(config);
-    psTimerStop();
-    psTraceReset();
-    pmConceptsDone();
-    pmConfigDone();
-    // ppMemCheck();
-    fprintf (stderr, "found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "ppImage");
+    ppImageCleanup(config, options);
     return EXIT_SUCCESS;
 }
Index: trunk/ppImage/src/ppImage.h
===================================================================
--- trunk/ppImage/src/ppImage.h	(revision 7508)
+++ trunk/ppImage/src/ppImage.h	(revision 7522)
@@ -7,5 +7,4 @@
 #include "psphot.h"
 #include "ppImageOptions.h"
-#include "ppMem.h"
 
 #define RECIPE_NAME "PHASE2"            // Name of the recipe to use
@@ -13,14 +12,17 @@
 
 // Get the configuration
-pmConfig *ppImageConfig(int *argc, char **argv);
+pmConfig *ppImageArguments(int *argc, char **argv);
 
 // Determine what type of camera, and initialise
-bool ppImageParseDetrend(ppImageOptions *options, pmConfig *config);
+ppImageOptions *ppImageParseCamera(pmConfig *config);
 
 // Loop over the input
-bool ppImageLoop(ppImageOptions *options, pmConfig *config);
+bool ppImageLoop(pmConfig *config, ppImageOptions *options);
+
+// free memory, check for leaks
+void ppImageCleanup (pmConfig *config, ppImageOptions *options);
 
 // perform the detrend analysis on the current readout
-bool ppImageDetrendReadout (ppImageOptions *options, pmConfig *config, pmFPAview *view);
+bool ppImageDetrendReadout (pmConfig *config, ppImageOptions *options, pmFPAview *view);
 
 bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options);
@@ -35,3 +37,3 @@
 bool ppImagePhotom (pmConfig *config, pmFPAview *view);
 
-#endif // Pau.
+#endif
Index: trunk/ppImage/src/ppImageArguments.c
===================================================================
--- trunk/ppImage/src/ppImageArguments.c	(revision 7522)
+++ trunk/ppImage/src/ppImageArguments.c	(revision 7522)
@@ -0,0 +1,68 @@
+#include "ppImage.h"
+
+static void usage (void) {
+    fprintf (stderr, "USAGE: ppImage [-file INPUT.fits] [-list INPUT.txt] OUTPUT\n");
+    exit (2);
+}
+
+pmConfig *ppImageArguments(int *argc, char **argv) {
+
+    int N;
+    bool status;
+
+    if (*argc == 1) usage ();
+
+    // load the site-wide configuration information
+    pmConfig *config = pmConfigRead(argc, argv);
+    if (config == NULL) {
+        psErrorStackPrint(stderr, "Can't find site configuration!\n");
+        exit(EXIT_FAILURE);
+    }
+
+    // Storage for other command-line arguments
+    config->arguments = psMetadataAlloc(); // The arguments, with default values
+
+    // save these recipe options until we have loaded the options
+    psMetadata *options = psMetadataAlloc ();
+    psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "PPIMAGE.OPTIONS",  PS_DATA_METADATA, "", options);
+
+    // the following options override the PPIMAGE recipe options
+
+    // recipe option: -usemask : override MASK setting in phase2.recipe
+    if ((N = psArgumentGet (*argc, argv, "-usemask"))) {
+	psArgumentRemove (N, argc, argv);
+	psMetadataAddBool (options, PS_LIST_TAIL, "MASK", PS_META_REPLACE, "", true);
+	psArgumentRemove (N, argc, argv);
+    }
+
+    // XXX add other PPIMAGE recipe options here 
+
+    // drop the local view on the options (saved on config->arguments)
+    psFree (options);
+
+    // the input file is a required argument; if not found, we will exit
+    status = pmConfigFileSetsMD (config->arguments, argc, argv, "INPUT", "-file", "-list");
+    if (!status) { usage ();}
+
+    // if these command-line options are supplied, load the file name lists into config->arguments
+    // override any configuration-specified source for these files
+    pmConfigFileSetsMD (config->arguments, argc, argv, "BIAS", "-bias", "-biaslist");
+    pmConfigFileSetsMD (config->arguments, argc, argv, "DARK", "-dark", "-darklist");
+    pmConfigFileSetsMD (config->arguments, argc, argv, "FLAT", "-flat", "-flatlist");
+    pmConfigFileSetsMD (config->arguments, argc, argv, "MASK", "-mask", "-masklist");
+    pmConfigFileSetsMD (config->arguments, argc, argv, "FRINGE", "-fringe", "-fringelist");
+
+    // chip selection is used to limit chips to be processed
+    if ((N = psArgumentGet (*argc, argv, "-chip"))) {
+	psArgumentRemove (N, argc, argv);
+	psMetadataAddStr (config->arguments, PS_LIST_TAIL, "CHIP_SELECTIONS", PS_DATA_STRING, "", psStringCopy(argv[N]));
+	psArgumentRemove (N, argc, argv);
+    }
+
+    if (*argc != 2) usage ();
+
+    // Add the input and output images (which remain on the command-line) to the arguments list
+    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "Name of the output image", argv[1]);
+
+    return config;
+}
Index: trunk/ppImage/src/ppImageCleanup.c
===================================================================
--- trunk/ppImage/src/ppImageCleanup.c	(revision 7522)
+++ trunk/ppImage/src/ppImageCleanup.c	(revision 7522)
@@ -0,0 +1,15 @@
+# include "ppImage.h"
+
+void ppImageCleanup (pmConfig *config, ppImageOptions *options) {
+
+    psFree(options);
+    psFree(config);
+
+    psTimerStop();
+    psMemCheckCorruption (true);
+    psTraceReset();
+    pmConceptsDone();
+    pmConfigDone();
+    fprintf (stderr, "found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "ppImage");
+    return;
+}
Index: trunk/ppImage/src/ppImageConfig.c
===================================================================
--- trunk/ppImage/src/ppImageConfig.c	(revision 7508)
+++ 	(revision )
@@ -1,64 +1,0 @@
-#include "ppImage.h"
-
-static void usage (void) {
-    fprintf (stderr, "USAGE: ppImage [-file INPUT.fits] [-list INPUT.txt] OUTPUT\n");
-    exit (2);
-}
-
-pmConfig *ppImageConfig(int *argc, char **argv)
-{
-
-    bool status;
-
-    if (*argc == 1) usage ();
-
-    // load the site-wide configuration information
-    pmConfig *config = pmConfigRead(argc, argv);
-    if (! config) {
-        psErrorStackPrint(stderr, "Can't find site configuration!\n");
-        exit(EXIT_FAILURE);
-    }
-
-    // Parse other command-line arguments, save for future use
-    config->arguments = psMetadataAlloc(); // The arguments, with default values
-
-    // if these command-line options are supplied, load the file name lists into config->arguments
-    // override any configuration-specified source for these files
-    status = pmConfigFileSetsMD (config->arguments, argc, argv, "BIAS", "-bias", "-biaslist");
-    status = pmConfigFileSetsMD (config->arguments, argc, argv, "DARK", "-dark", "-darklist");
-    status = pmConfigFileSetsMD (config->arguments, argc, argv, "FLAT", "-flat", "-flatlist");
-    status = pmConfigFileSetsMD (config->arguments, argc, argv, "MASK", "-mask", "-masklist");
-    status = pmConfigFileSetsMD (config->arguments, argc, argv, "FRINGE", "-fringe", "-fringelist");
-
-    // the input file is a required argument; if not found, we will exit
-    status = pmConfigFileSetsMD (config->arguments, argc, argv, "INPUT", "-file", "-list");
-    if (!status) { usage ();}
-
-    if (! psArgumentParse(config->arguments, argc, argv) || *argc != 2) {
-	usage ();
-    }
-
-    // Add the input and output images (which remain on the command-line) to the arguments list
-    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "Name of the output image", argv[1]);
-
-    // the input image(s) are required arguments
-    // the first one defines the camera
-    status = false;
-    pmFPAfileFromArgs (&status, config, "PPIMAGE.INPUT", "INPUT");
-    if (!status) {
-	psAbort (__func__, "missing INPUT entry");
-    }
-
-    // Define database handle, if used
-#if 0
-    config->database = pmConfigDB(config->site);
-#endif
-
-    return config;
-}
-
-    // other command-line options
-    // XXX not sure how these are to be used at the moment
-    // psMetadataAddStr(config->arguments, PS_LIST_TAIL, "-key", 0, "exposure ID", "");
-    // psMetadataAddS32(config->arguments, PS_LIST_TAIL, "-chip", 0, "Chip number to process (if positive)", -1);
-
Index: trunk/ppImage/src/ppImageDetrendReadout.c
===================================================================
--- trunk/ppImage/src/ppImageDetrendReadout.c	(revision 7508)
+++ trunk/ppImage/src/ppImageDetrendReadout.c	(revision 7522)
@@ -1,5 +1,5 @@
 #include "ppImage.h"
 
-bool ppImageDetrendReadout (ppImageOptions *options, pmConfig *config, pmFPAview *view)
+bool ppImageDetrendReadout (pmConfig *config, ppImageOptions *options, pmFPAview *view)
 {
     // construct a view for the detrend images (which have only one readout)
Index: trunk/ppImage/src/ppImageLoop.c
===================================================================
--- trunk/ppImage/src/ppImageLoop.c	(revision 7508)
+++ trunk/ppImage/src/ppImageLoop.c	(revision 7522)
@@ -1,5 +1,5 @@
 # include "ppImage.h"
 
-bool ppImageLoop (ppImageOptions *options, pmConfig *config) {
+bool ppImageLoop (pmConfig *config, ppImageOptions *options) {
 
     bool status;
@@ -35,5 +35,5 @@
 
 		// perform the detrend analysis
-		ppImageDetrendReadout (options, config, view);
+		ppImageDetrendReadout (config, options, view);
 
 		if (options->doBin1) ppImageRebinReadout (config, view, "PPIMAGE.BIN1");
Index: trunk/ppImage/src/ppImageParseCamera.c
===================================================================
--- trunk/ppImage/src/ppImageParseCamera.c	(revision 7522)
+++ trunk/ppImage/src/ppImageParseCamera.c	(revision 7522)
@@ -0,0 +1,84 @@
+# include "ppImage.h"
+
+// XXX clean up error checks: return NULL, not psAbort
+ppImageOptions *ppImageParseCamera (pmConfig *config) {
+
+    bool status = false;
+
+    // the input image defines the camera
+    pmFPAfile *input = pmFPAfileFromArgs (&status, config, "PPIMAGE.INPUT", "INPUT");
+    if (!status) {
+	psError(PS_ERR_IO, false, "Failed to build FPA from PPIMAGE.INPUT");
+	return NULL;
+    }
+
+    // add recipe options supplied on command line
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes,   "PHASE2");
+    psMetadata *arglist = psMetadataLookupPtr (&status, config->arguments, "PPIMAGE.OPTIONS");
+    psMetadataCopy (recipe, arglist);
+
+    // parse the options from the metadata format to the ppImageOptions structure
+    ppImageOptions *options = ppImageOptionsParse (config);
+
+    // the following files are output targets
+    pmFPAfileDefine (config->files, config->camera, input->fpa, "PPIMAGE.OUTPUT");
+
+    // the following are defined from the argument list, if given, 
+    // otherwise they revert to the config information
+    // not all input or output images are used in a given recipe
+    if (options->doBias) {
+	bool status = false;
+	pmFPAfileFromArgs (&status, config, "PPIMAGE.BIAS", "BIAS");
+	pmFPAfileFromConf (&status, config, "PPIMAGE.BIAS", input->fpa);
+	if (!status) psAbort ("ppImageParseDetrend", "can't find a bias image source");
+    }
+    if (options->doDark) {
+	bool status = false;
+	pmFPAfileFromArgs (&status, config, "PPIMAGE.DARK", "DARK");
+	pmFPAfileFromConf (&status, config, "PPIMAGE.DARK", input->fpa);
+	if (!status) psAbort ("ppImageParseDetrend", "can't find a dark image source");
+    }
+    if (options->doMask) {
+	bool status = false;
+	pmFPAfileFromArgs (&status, config, "PPIMAGE.MASK", "MASK");
+	pmFPAfileFromConf (&status, config, "PPIMAGE.MASK", input->fpa);
+	if (!status) psAbort ("ppImageParseDetrend", "can't find a mask image source");
+    }
+    if (options->doFlat) {
+	bool status = false;
+	pmFPAfileFromArgs (&status, config, "PPIMAGE.FLAT", "FLAT");
+	pmFPAfileFromConf (&status, config, "PPIMAGE.FLAT", input->fpa);
+	if (!status) psAbort ("ppImageParseDetrend", "can't find a flat image source");
+    }
+    if (options->doBin1) {
+	pmFPAfile *file = pmFPAfileFromFPA (config, input->fpa, options->xBin1, options->yBin1, "PPIMAGE.BIN1");
+	pmFPAfileDefine (config->files, config->camera, file->fpa, "PPIMAGE.JPEG1");
+    }
+    if (options->doBin2) {
+	pmFPAfile *file = pmFPAfileFromFPA (config, input->fpa, options->xBin2, options->yBin2, "PPIMAGE.BIN2");
+	pmFPAfileDefine (config->files, config->camera, file->fpa, "PPIMAGE.JPEG2");
+    }
+
+    // ppImage is supplied with an output name, which may be used by multiple
+    // output files to construct the output names.  supply this value to the
+    // files which are write types.
+    char *output = psMetadataLookupPtr(&status, config->arguments, "OUTPUT");
+    pmFPAfileAddFileNames (config->files, "OUTPUT", output, PM_FPA_MODE_WRITE);
+
+    // Chip selection: turn on only the chips specified (pass status to suppress missing-key log msg)
+    char *chipLine = psMetadataLookupStr(&status, config->arguments, "CHIP_SELECTIONS");
+    psArray *chips = psStringSplitArray (chipLine, ",", false);
+    if (chips->n > 0) {
+	pmFPASelectChip (input->fpa, -1, true); // deselect all chips
+	for (int i = 0; i < chips->n; i++) {
+	    int chipNum = atoi(chips->data[i]);
+	    if (! pmFPASelectChip(input->fpa, chipNum, false)) {
+		psError(PS_ERR_IO, false, "Chip number %d doesn't exist in camera.\n", chipNum);
+		return false;
+	    }
+        }
+    }
+    psFree (chips);
+
+    return (options);
+}
Index: trunk/ppImage/src/ppImagePhot.c
===================================================================
--- trunk/ppImage/src/ppImagePhot.c	(revision 7508)
+++ 	(revision )
@@ -1,94 +1,0 @@
-# include "ppImage.h"
-
-bool ppImagePhotom (pmConfig *config, pmFPAview *view) {
-
-    bool status;
-    pmCell *cell;
-    pmReadout *readout;
-
-    psphotModelGroupInit ();
-
-    // select recipe options supplied on command line
-    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes,   "PSPHOT");
-
-    // set default recipe values here
-    // XXX place this in a psphot library function?
-    psMetadataAddStr (recipe, PS_LIST_TAIL, "FITMODE",         PS_META_NO_REPLACE, "default fitting mode", "NONE");
-    psMetadataAddStr (recipe, PS_LIST_TAIL, "PHOTCODE",        PS_META_NO_REPLACE, "default photcode",     "NONE");
-    psMetadataAddStr (recipe, PS_LIST_TAIL, "BREAK_POINT",     PS_META_NO_REPLACE, "default break point",  "NONE");
-    psMetadataAddF32 (recipe, PS_LIST_TAIL, "ZERO_PT",         PS_META_NO_REPLACE, "default zero point",    25.00);
-    psMetadataAddS32 (recipe, PS_LIST_TAIL, "BACKGROUND.XBIN", PS_META_NO_REPLACE, "default binning",          64);
-    psMetadataAddS32 (recipe, PS_LIST_TAIL, "BACKGROUND.YBIN", PS_META_NO_REPLACE, "default binning",          64);
-
-    // find or define a pmFPAfile PSPHOT.INPUT
-    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSPHOT.INPUT");
-    if (!status) {
-
-	// psphotReadout requires a pmFPAfile supplied with the name PSPHOT.INPUT
-	// create a pmFPAfile which points at PPIMAGE.OUTPUT
-	// mode is 'REFERENCE' to prevent double frees of the fpa
-	pmFPAfile *output = psMetadataLookupPtr (&status, config->files, "PPIMAGE.OUTPUT");
-	input = pmFPAfileDefine (config->files, config->camera, output->fpa, "PSPHOT.INPUT");
-	input->mode = PM_FPA_MODE_REFERENCE;
-
-	pmFPAfileDefine (config->files, config->camera, input->fpa, "PSPHOT.OUTPUT");
-
-	// supply the output name (from cmd-line) to all output (WRITE) files
-	// XXX does this cause trouble with existing files?
-	char *outname = psMetadataLookupPtr(&status, config->arguments, "OUTPUT");
-	pmFPAfileAddFileNames (config->files, "OUTPUT", outname, PM_FPA_MODE_WRITE);
-    }
-
-    // XXX add the option output files here
-
-    // int DX = psMetadataLookupS32 (&status, recipe, "BACKGROUND.XBIN");
-    // int DY = psMetadataLookupS32 (&status, recipe, "BACKGROUND.YBIN");
-
-    // we only was to operate on PSPHOT pmFPAfiles here:
-    pmFPAfileActivate (config->files, false, NULL);
-    pmFPAfileActivate (config->files, true, "PSPHOT.INPUT");
-    pmFPAfileActivate (config->files, true, "PSPHOT.RESID");
-    pmFPAfileActivate (config->files, true, "PSPHOT.OUTPUT");
-
-    pmFPAfileActivate (config->files, true, "PSPHOT.BACKSUB");
-    pmFPAfileActivate (config->files, true, "PSPHOT.BACKGND");
-    pmFPAfileActivate (config->files, true, "PSPHOT.BACKMDL");
-
-
-    // iterate over the cells in the current chip
-    // view->cell = -1;
-
-    while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
-	psLogMsg ("ppImagePhot", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-	if (! cell->process || ! cell->file_exists) { continue; }
-	pmFPAfileIOChecks (config->files, view, PM_FPA_BEFORE);
-
-	// process each of the readouts
-	while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
-	    pmFPAfileIOChecks (config->files, view, PM_FPA_BEFORE);
-	    if (! readout->data_exists) { continue; }
-
-	    // run the actual photometry analysis
-	    psphotReadout (config, view);
-
-	    pmFPAfileIOChecks (config->files, view, PM_FPA_AFTER);
-	}
-	pmFPAfileIOChecks (config->files, view, PM_FPA_AFTER);
-    }
-
-    // de-activate the PSPHOT image files, activate the PPIMAGE ones
-    pmFPAfileActivate (config->files, false, NULL);
-    pmFPAfileActivate (config->files, true, "PPIMAGE.INPUT");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.BIAS");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.DARK");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.MASK");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.FLAT");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.OUTPUT");
-
-    pmFPAfileActivate (config->files, true, "PPIMAGE.BIN1");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.JPEG1");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.BIN2");
-    pmFPAfileActivate (config->files, true, "PPIMAGE.JPEG2");
-
-    return true;
-}
Index: trunk/ppImage/src/ppImagePhotom.c
===================================================================
--- trunk/ppImage/src/ppImagePhotom.c	(revision 7522)
+++ trunk/ppImage/src/ppImagePhotom.c	(revision 7522)
@@ -0,0 +1,94 @@
+# include "ppImage.h"
+
+bool ppImagePhotom (pmConfig *config, pmFPAview *view) {
+
+    bool status;
+    pmCell *cell;
+    pmReadout *readout;
+
+    psphotModelGroupInit ();
+
+    // select recipe options supplied on command line
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes,   "PSPHOT");
+
+    // set default recipe values here
+    // XXX place this in a psphot library function?
+    psMetadataAddStr (recipe, PS_LIST_TAIL, "FITMODE",         PS_META_NO_REPLACE, "default fitting mode", "NONE");
+    psMetadataAddStr (recipe, PS_LIST_TAIL, "PHOTCODE",        PS_META_NO_REPLACE, "default photcode",     "NONE");
+    psMetadataAddStr (recipe, PS_LIST_TAIL, "BREAK_POINT",     PS_META_NO_REPLACE, "default break point",  "NONE");
+    psMetadataAddF32 (recipe, PS_LIST_TAIL, "ZERO_PT",         PS_META_NO_REPLACE, "default zero point",    25.00);
+    psMetadataAddS32 (recipe, PS_LIST_TAIL, "BACKGROUND.XBIN", PS_META_NO_REPLACE, "default binning",          64);
+    psMetadataAddS32 (recipe, PS_LIST_TAIL, "BACKGROUND.YBIN", PS_META_NO_REPLACE, "default binning",          64);
+
+    // find or define a pmFPAfile PSPHOT.INPUT
+    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSPHOT.INPUT");
+    if (!status) {
+
+	// psphotReadout requires a pmFPAfile supplied with the name PSPHOT.INPUT
+	// create a pmFPAfile which points at PPIMAGE.OUTPUT
+	// mode is 'REFERENCE' to prevent double frees of the fpa
+	pmFPAfile *output = psMetadataLookupPtr (&status, config->files, "PPIMAGE.OUTPUT");
+	input = pmFPAfileDefine (config->files, config->camera, output->fpa, "PSPHOT.INPUT");
+	input->mode = PM_FPA_MODE_REFERENCE;
+
+	pmFPAfileDefine (config->files, config->camera, input->fpa, "PSPHOT.OUTPUT");
+
+	// supply the output name (from cmd-line) to all output (WRITE) files
+	// XXX does this cause trouble with existing files?
+	char *outname = psMetadataLookupPtr(&status, config->arguments, "OUTPUT");
+	pmFPAfileAddFileNames (config->files, "OUTPUT", outname, PM_FPA_MODE_WRITE);
+    }
+
+    // XXX add the option output files here
+
+    // int DX = psMetadataLookupS32 (&status, recipe, "BACKGROUND.XBIN");
+    // int DY = psMetadataLookupS32 (&status, recipe, "BACKGROUND.YBIN");
+
+    // we only was to operate on PSPHOT pmFPAfiles here:
+    pmFPAfileActivate (config->files, false, NULL);
+    pmFPAfileActivate (config->files, true, "PSPHOT.INPUT");
+    pmFPAfileActivate (config->files, true, "PSPHOT.RESID");
+    pmFPAfileActivate (config->files, true, "PSPHOT.OUTPUT");
+
+    pmFPAfileActivate (config->files, true, "PSPHOT.BACKSUB");
+    pmFPAfileActivate (config->files, true, "PSPHOT.BACKGND");
+    pmFPAfileActivate (config->files, true, "PSPHOT.BACKMDL");
+
+
+    // iterate over the cells in the current chip
+    // view->cell = -1;
+
+    while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
+	psLogMsg ("ppImagePhot", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+	if (! cell->process || ! cell->file_exists) { continue; }
+	pmFPAfileIOChecks (config->files, view, PM_FPA_BEFORE);
+
+	// process each of the readouts
+	while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
+	    pmFPAfileIOChecks (config->files, view, PM_FPA_BEFORE);
+	    if (! readout->data_exists) { continue; }
+
+	    // run the actual photometry analysis
+	    psphotReadout (config, view);
+
+	    pmFPAfileIOChecks (config->files, view, PM_FPA_AFTER);
+	}
+	pmFPAfileIOChecks (config->files, view, PM_FPA_AFTER);
+    }
+
+    // de-activate the PSPHOT image files, activate the PPIMAGE ones
+    pmFPAfileActivate (config->files, false, NULL);
+    pmFPAfileActivate (config->files, true, "PPIMAGE.INPUT");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.BIAS");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.DARK");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.MASK");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.FLAT");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.OUTPUT");
+
+    pmFPAfileActivate (config->files, true, "PPIMAGE.BIN1");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.JPEG1");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.BIN2");
+    pmFPAfileActivate (config->files, true, "PPIMAGE.JPEG2");
+
+    return true;
+}
