Index: /branches/haf_branches/videophot2010/ppImage/autogen.sh
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/autogen.sh	(revision 29946)
+++ /branches/haf_branches/videophot2010/ppImage/autogen.sh	(revision 29947)
@@ -8,5 +8,5 @@
 cd $srcdir
 
-PROJECT=ppImage
+PROJECT=psvideophot
 TEST_TYPE=-f
 # change this to be a unique filename in the top level dir
Index: /branches/haf_branches/videophot2010/ppImage/configure.ac
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/configure.ac	(revision 29946)
+++ /branches/haf_branches/videophot2010/ppImage/configure.ac	(revision 29947)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.61)
 
-AC_INIT([ppImage], [1.1.0], [ipp-support@ifa.hawaii.edu])
+AC_INIT([psvideophot], [1.1.0], [ipp-support@ifa.hawaii.edu])
 AC_CONFIG_SRCDIR([src])
 
@@ -28,6 +28,6 @@
 IPP_VERSION
 
-AC_SUBST([PPIMAGE_CFLAGS])
-AC_SUBST([PPIMAGE_LIBS])
+AC_SUBST([PSVIDEOPHOT_CFLAGS])
+AC_SUBST([PSVIDEOPHOT_LIBS])
 
 AC_CONFIG_FILES([
Index: /branches/haf_branches/videophot2010/ppImage/src/Makefile.am
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/Makefile.am	(revision 29946)
+++ /branches/haf_branches/videophot2010/ppImage/src/Makefile.am	(revision 29947)
@@ -1,65 +1,42 @@
-bin_PROGRAMS = ppImage
+bin_PROGRAMS = psvideophot
 
 noinst_HEADERS = \
-	ppImage.h 
+	psvideophot.h 
 
 if HAVE_SVNVERSION
-PPIMAGE_VERSION=`$(SVNVERSION) ..`
+PSVIDEOPHOT_VERSION=`$(SVNVERSION) ..`
 else
-PPIMAGE_VERSION="UNKNOWN"
+PSVIDEOPHOT_VERSION="UNKNOWN"
 endif
 
 if HAVE_SVN
-PPIMAGE_BRANCH=`$(SVN) info .. | $(SED) -n -e '/URL:/ h' -e '/Repository Root:/ { x; H; x; s|Repository Root: \(.*\)\nURL: \1\(.*\)|\2| ; s|^/|| ; s|/[a-zA-Z]*/src.*|| ; p }'`
-PPIMAGE_SOURCE=`$(SVN) info | $(SED) -n -e 's/Repository UUID: // p'`
+PSVIDEOPHOT_BRANCH=`$(SVN) info .. | $(SED) -n -e '/URL:/ h' -e '/Repository Root:/ { x; H; x; s|Repository Root: \(.*\)\nURL: \1\(.*\)|\2| ; s|^/|| ; s|/[a-zA-Z]*/src.*|| ; p }'`
+PSVIDEOPHOT_SOURCE=`$(SVN) info | $(SED) -n -e 's/Repository UUID: // p'`
 else
-PPIMAGE_BRANCH="UNKNOWN"
-PPIMAGE_SOURCE="UNKNOWN"
+PSVIDEOPHOT_BRANCH="UNKNOWN"
+PSVIDEOPHOT_SOURCE="UNKNOWN"
 endif
 
-# Force recompilation of ppImageVersion.c, since it gets the version information
-ppImageVersion.c: ppImageVersionDefinitions.h
-ppImageVersionDefinitions.h: ppImageVersionDefinitions.h.in FORCE
-	-$(RM) ppImageVersionDefinitions.h
-	$(SED) -e "s|@PPIMAGE_VERSION@|\"$(PPIMAGE_VERSION)\"|" -e "s|@PPIMAGE_BRANCH@|\"$(PPIMAGE_BRANCH)\"|" -e "s|@PPIMAGE_SOURCE@|\"$(PPIMAGE_SOURCE)\"|" ppImageVersionDefinitions.h.in > ppImageVersionDefinitions.h
+# Force recompilation of psvideophotVersion.c, since it gets the version information
+psvideophotVersion.c: psvideophotVersionDefinitions.h
+psvideophotVersionDefinitions.h: psvideophotVersionDefinitions.h.in FORCE
+	-$(RM) psvideophotVersionDefinitions.h
+	$(SED) -e "s|@PSVIDEOPHOT_VERSION@|\"$(PSVIDEOPHOT_VERSION)\"|" -e "s|@PSVIDEOPHOT_BRANCH@|\"$(PSVIDEOPHOT_BRANCH)\"|" -e "s|@PSVIDEOPHOT_SOURCE@|\"$(PSVIDEOPHOT_SOURCE)\"|" psvideophotVersionDefinitions.h.in > psvideophotVersionDefinitions.h
 FORCE: ;
 
-BUILT_SOURCES = ppImageVersionDefinitions.h
+BUILT_SOURCES = psvideophotVersionDefinitions.h
 
-ppImage_CFLAGS = $(PPIMAGE_CFLAGS) $(PPSTATS_CFLAGS) $(PSASTRO_CFLAGS) $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
-ppImage_LDFLAGS = $(PPIMAGE_LIBS) $(PSASTRO_LIBS) $(PPSTATS_LIBS) $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
-ppImage_SOURCES = \
-	ppImage.c \
-	ppImageArguments.c \
-	ppImageParseCamera.c \
-	ppImageLoop.c \
-	ppImageCleanup.c \
-	ppImageOptions.c \
-	ppImageDetrendReadout.c \
-	ppImageDetrendRecord.c \
-	ppImageDetrendNonLinear.c \
-	ppImageDetrendFringe.c \
-	ppImageDetrendFree.c \
-	ppImageDetrendPattern.c \
-	ppImageRebinReadout.c \
-	ppImageMosaic.c \
-	ppImageMaskStats.c \
-	ppImagePhotom.c \
-	ppImageAstrom.c \
-	ppImageAddstar.c \
-	ppImageStatsOutput.c \
-	ppImagePixelStats.c \
-	ppImageMetadataStats.c \
-	ppImageReplaceBackground.c \
-	ppImageMeasureCrosstalk.c \
-	ppImageCorrectCrosstalk.c \
-	ppImageDefineFile.c \
-	ppImageSetMaskBits.c \
-	ppImageBurntoolMask.c \
-	ppImageParityFlip.c \
-	ppImageCheckCTE.c \
-	ppImageFileCheck.c \
-	ppImageVersion.c \
-	ppImageMemory.c
+psvideophot_CFLAGS = $(PSVIDEOPHOT_CFLAGS) $(PPSTATS_CFLAGS) $(PSASTRO_CFLAGS) $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
+psvideophot_LDFLAGS = $(PSVIDEOPHOT_LIBS) $(PSASTRO_LIBS) $(PPSTATS_LIBS) $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
+psvideophot_SOURCES = \
+	psvideophot.c \
+	psvideophotArguments.c \
+	psvideophotParseCamera.c \
+	psvideophotOptions.c \
+	psvideophotCleanup.c \
+	psvideophotDefineFile.c \
+	psvideoLoop.c \
+	psvideophotFileCheck.c \
+	psvideophotVersion.c 
 
 CLEANFILES = *~
Index: anches/haf_branches/videophot2010/ppImage/src/ppFocus.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppFocus.c	(revision 29946)
+++ 	(revision )
@@ -1,74 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-int main(int argc, char **argv) {
-
-    psLibInit(NULL);
-
-    psTimerStart(TIMER_TOTAL);
-
-    // Parse the configuration and arguments
-    // Open the input image(s)
-    // Determine camera, format from header if not already defined
-    // Construct camera in preparation for reading
-    pmConfig *config = ppFocusArguments(argc, argv);
-    if (config == NULL) {
-        psErrorStackPrint(stderr, " ");
-        exit(1);
-    }
-
-    // we search the argument data for the named fileset (argname)
-    psArray *infiles = psMetadataLookupPtr(NULL, config->arguments, "INPUT");
-    if (!infiles) {
-        psTrace("pmFPAfile", 5, "Failed to find INPUT in argument list");
-        exit(1);
-    }
-
-    // allocate vectors for analysis
-    psVector *focus = psVectorAllocEmpty(infiles->n, PS_TYPE_F32);
-    psVector *fwhm = psVectorAllocEmpty(infiles->n, PS_TYPE_F32);
-
-    for (int i = 0; i < infiles->n; i++) {
-
-        // define recipe options
-        // define the active I/O files
-        ppImageOptions *options = ppFocusParseCamera(config, i);
-        if (options == NULL) {
-            psErrorStackPrint(stderr, " ");
-            exit(1);
-        }
-
-        // Image Arithmetic Loop
-        // XXX ppFocus REQUIRES photom: for it to be true?
-        //
-        if (!ppImageLoop(config, options)) {
-            psErrorStackPrint(stderr, " ");
-            exit(1);
-        }
-
-        // determine FWHM at reference location in image
-        // (also removes PPIMAGE.INPUT from config->files)
-        ppFocusGetFWHM (config, focus, fwhm);
-
-        ppFocusDropCamera (config);
-        psFree (options);
-    }
-
-    ppFocusFitFWHM (config, focus, fwhm);
-
-    psLogMsg ("ppFocus", 3, "complete ppFocus run: %f sec\n", psTimerMark (TIMER_TOTAL));
-
-    // Cleaning up
-    psFree (focus);
-    psFree (fwhm);
-    ppImageCleanup(config, NULL);
-    return EXIT_SUCCESS;
-}
-
-// ppFocus is a lot like ppImage, but with a few important differences:
-// - the input list is a set of independent images (not multiple files for a single image)
-// - each pass to ppImageLoop performs the analysis on a different pmFPAfile
-// - after each ppImageLoop, grap the input pmFPAfile and extract the FWHM stats
Index: anches/haf_branches/videophot2010/ppImage/src/ppFocusArguments.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppFocusArguments.c	(revision 29946)
+++ 	(revision )
@@ -1,72 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-static void usage (void) {
-    fprintf (stderr, "USAGE: ppFocus [-file focus.*.fits] [-list INPUT.txt] OUTPUT\n");
-    exit (2);
-}
-
-pmConfig *ppFocusArguments(int argc, char **argv) {
-
-    int N;
-    bool status;
-
-    if (argc == 1) usage ();
-
-    // load the site-wide configuration information
-    pmConfig *config = pmConfigRead(&argc, argv, RECIPE_NAME);
-    if (config == NULL) {
-        psErrorStackPrint(stderr, "Can't find site configuration!\n");
-        exit(EXIT_FAILURE);
-    }
-
-    // save the following additional recipe values based on command-line options
-    // these options override the PPIMAGE recipe values loaded from recipe files
-    psMetadata *options = pmConfigRecipeOptions (config, RECIPE_NAME);
-
-    // 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
-
-    // 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, "",
-                          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: anches/haf_branches/videophot2010/ppImage/src/ppFocusFitFWHM.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppFocusFitFWHM.c	(revision 29946)
+++ 	(revision )
@@ -1,30 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-bool ppFocusFitFWHM (pmConfig *config, psVector *focus, psVector *fwhm) {
-
-    float minFocus;
-
-    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2);
-
-    if (!psVectorFitPolynomial1D (poly, NULL, 0, fwhm, NULL, focus)) {
-	psError (PS_ERR_UNKNOWN, false, "failed to fit focus/fwhm trend; invalid image data?");
-	return false;
-    }
-
-    if (poly->coeff[2] <= 0.0) {
-	psLogMsg ("ppFocus", 3, "poor focus fit: zero or negative curvature\n");
-	psLogMsg ("ppFocus", 3, "fit coeffs: %f  %f  %f\n", 
-		  poly->coeff[0], poly->coeff[1], poly->coeff[2]);
-    }
-    
-    minFocus = -0.5 * poly->coeff[1] / poly->coeff[2];
-    psLogMsg ("ppFocus", 3, "best fit focus: %f\n", minFocus);
-    psLogMsg ("ppFocus", 3, "fwhm @ min: %f\n", psPolynomial1DEval (poly, minFocus));
-    
-    psFree (poly);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppFocusGetFWHM.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppFocusGetFWHM.c	(revision 29946)
+++ 	(revision )
@@ -1,79 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-bool ppFocusGetFWHM (pmConfig *config, psVector *focus, psVector *fwhm) {
-
-    bool status;
-    pmChip *chip;
-    pmCell *cell;
-    pmReadout *readout;
-    psMetadata *header;
-    float FOCUS, FWHM, FWHM_X, FWHM_Y, FWHMsum;
-    int FWHMnum;
-
-    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSPHOT.OUTPUT");
-    if (!status) {
-	psErrorStackPrint(stderr, "Can't find input data!\n");
-	exit(EXIT_FAILURE);
-    }
-
-    pmFPAview *view = pmFPAviewAlloc (0);
-
-    // - find readouts with measured PSFs
-    // - measure the average central FWHM for each PSF
-    FWHMsum = 0.0;
-    FWHMnum = 0;
-
-    while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
-        psLogMsg ("ppImageLoop", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
-        if (!chip->process || !chip->file_exists) { continue; }
-
-	while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
-            psLogMsg ("ppImageLoop", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-            if (!cell->process || !cell->file_exists) { continue; }
-
-	    // process each of the readouts
-	    while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
-		if (!readout->data_exists) { continue; }
-
-		// get average FWHM
-		// psphotReadout writes the FWHM values into the PSPHOT.HEADER table
-		// the source of this value depends on the psphot options.
-		// - if breakPoint is set to PEAKS, the value will not be defined
-		// - if breakPoint is set to MOMENTS, the PSFSTAR moments are used
-		// - in all other cases, the psf model is used
-		header = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.HEADER");
-		if (header == NULL) {
-		    psError(PS_ERR_IO, false, "Missing header in ppFocus");
-		    continue;
-		}
-
-		FWHM_X = psMetadataLookupF32 (&status, header, "FWHM_X");
-		FWHM_Y = psMetadataLookupF32 (&status, header, "FWHM_Y");
-
-		FWHMsum += 0.5*(FWHM_X + FWHM_Y);
-		FWHMnum ++;
-
-		psLogMsg ("ppFocus", 4, "focus pt: %f,%f, fwhm sum: %f, fwhm num: %d\n", FWHM_X, FWHM_Y, FWHMsum, FWHMnum);
-	    }
-	}
-    }
-
-    FWHM = FWHMsum / FWHMnum;
-
-    FOCUS = psMetadataLookupF32 (&status, input->fpa->concepts, "FPA.FOCUS");
-
-    fwhm->data.F32[fwhm->n] = FWHM;
-    focus->data.F32[focus->n] = FOCUS;
-
-    psVectorExtend (fwhm, 10, 1);
-    psVectorExtend (focus, 10, 1);
-
-    psLogMsg ("ppFocus", 4, "focus: %f, fwhm: %f (%d)\n", FOCUS, FWHM, FWHMnum);
-
-    psFree (view);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppFocusParseCamera.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppFocusParseCamera.c	(revision 29946)
+++ 	(revision )
@@ -1,133 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-// XXX clean up error checks: return NULL, not psAbort
-ppImageOptions *ppFocusParseCamera (pmConfig *config, int entry) {
-
-    bool status = false;
-
-    // the first input image defines the camera, and all recipes and options that follow
-    // select only the first file from the INPUT array
-    pmFPAfile *input = pmFPAfileDefineSingleFromArgs (&status, config, "PPIMAGE.INPUT", "INPUT", entry);
-    if (!status) {
-        psError(PS_ERR_IO, false, "Failed to build FPA from PPIMAGE.INPUT");
-        return NULL;
-    }
-
-    // parse the options from the metadata format to the ppImageOptions structure
-    ppImageOptions *options = ppImageOptionsParse (config);
-
-    // the following are defined from the argument list, if given,
-    // otherwise they revert to the config information or detrend database if specified
-    // not all input or output images are used in a given recipe
-    if (options->doBias) {
-	if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.BIAS", "BIAS", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_BIAS)) {
-	    psError (PS_ERR_IO, false, "Can't find a bias image source");
-	    return NULL;
-	}
-    }
-    if (options->doDark) {
-	if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.DARK", "DARK", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_DARK)) {
-	    psError (PS_ERR_IO, false, "Can't find a dark image source");
-	    return NULL;
-	}
-    }
-    if (options->doMask) {
-	if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.MASK", "MASK", PM_FPA_FILE_MASK, PM_DETREND_TYPE_MASK)) {
-	    psError (PS_ERR_IO, false, "Can't find a mask image source");
-	    return NULL;
-	}
-    }
-    if (options->doFlat) {
-	if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.FLAT", "FLAT", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_FLAT)) {
-	    psError (PS_ERR_IO, false, "Can't find a shutter image source");
-	    return NULL;
-	}
-    }
-
-    // the following files are output targets
-    pmFPAfile *output = pmFPAfileDefineOutput (config, input->fpa, "PPIMAGE.OUTPUT");
-    pmFPAfile *byChip = pmFPAfileDefineNewCamera (config, "PPIMAGE.OUTPUT.CHIP");
-    pmFPAfile *byFPA1 = pmFPAfileDefineNewCamera (config, "PPIMAGE.OUTPUT.FPA1");
-    pmFPAfile *byFPA2 = pmFPAfileDefineNewCamera (config, "PPIMAGE.OUTPUT.FPA2");
-
-    // save any of these files?
-    output->save = options->BaseFITS;
-    byChip->save = options->ChipFITS;
-    byFPA1->save = options->FPA1FITS;
-    byFPA2->save = options->FPA2FITS;
-
-    // output is used as a carrier: input to byChip
-    output->freeLevel = PM_FPA_LEVEL_CHIP;
-
-    // define the binned target files (which may just be carriers for some camera configurations)
-    pmFPAfile *bin1 = pmFPAfileDefineFromFPA (config, byChip->fpa, options->xBin1, options->yBin1, "PPIMAGE.BIN1");
-    pmFPAfile *bin2 = pmFPAfileDefineFromFPA (config, byChip->fpa, options->xBin2, options->yBin2, "PPIMAGE.BIN2");
-
-    // bin1 and bin2 are used as carriers: input for byFPA1, byFPA2
-    bin1->freeLevel = PM_FPA_LEVEL_FPA;
-    bin2->freeLevel = PM_FPA_LEVEL_FPA;
-
-    pmFPAfile *jpg1 = pmFPAfileDefineOutput (config, byFPA1->fpa, "PPIMAGE.JPEG1");
-    pmFPAfile *jpg2 = pmFPAfileDefineOutput (config, byFPA2->fpa, "PPIMAGE.JPEG2");
-
-    // XXX we could potentially not define these pmFPAfiles if no output is requested...
-    bin1->save = options->Bin1FITS;
-    bin2->save = options->Bin2FITS;
-    jpg1->save = options->Bin1JPEG;
-    jpg2->save = options->Bin2JPEG;
-
-    // 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);
-}
-
-// remove from config all pmFPAfiles which could have been added (ignore missing entries)
-void ppFocusDropCamera (pmConfig *config) {
-
-    psMetadataRemoveKey (config->files, "PPIMAGE.INPUT");
-
-    psMetadataRemoveKey (config->files, "PPIMAGE.BIAS");
-    psMetadataRemoveKey (config->files, "PPIMAGE.DARK");
-    psMetadataRemoveKey (config->files, "PPIMAGE.MASK");
-    psMetadataRemoveKey (config->files, "PPIMAGE.FLAT");
-
-    psMetadataRemoveKey (config->files, "PPIMAGE.OUTPUT");
-    psMetadataRemoveKey (config->files, "PPIMAGE.OUTPUT.CHIP");
-    psMetadataRemoveKey (config->files, "PPIMAGE.OUTPUT.FPA1");
-    psMetadataRemoveKey (config->files, "PPIMAGE.OUTPUT.FPA2");
-
-    psMetadataRemoveKey (config->files, "PPIMAGE.BIN1");
-    psMetadataRemoveKey (config->files, "PPIMAGE.BIN2");
-
-    psMetadataRemoveKey (config->files, "PPIMAGE.JPEG1");
-    psMetadataRemoveKey (config->files, "PPIMAGE.JPEG2");
-
-    psMetadataRemoveKey (config->files, "PSPHOT.INPUT");
-    psMetadataRemoveKey (config->files, "PSPHOT.OUTPUT");
-    psMetadataRemoveKey (config->files, "PSPHOT.RESID");
-    psMetadataRemoveKey (config->files, "PSPHOT.BACKMDL");
-    psMetadataRemoveKey (config->files, "PSPHOT.BACKGND");
-    psMetadataRemoveKey (config->files, "PSPHOT.BACKSUB");
-    psMetadataRemoveKey (config->files, "PSPHOT.PSF.LOAD");
-    psMetadataRemoveKey (config->files, "PSPHOT.PSF.SAVE");
-
-    return;
-}
-
Index: anches/haf_branches/videophot2010/ppImage/src/ppImage.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImage.c	(revision 29946)
+++ 	(revision )
@@ -1,48 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-int main(int argc, char **argv) {
-
-    psLibInit(NULL);
-
-    psTimerStart(TIMER_TOTAL);
-
-    // Parse the configuration and arguments
-    // Open the input image(s)
-    // Determine camera, format from header if not already defined
-    // Construct camera in preparation for reading
-    pmConfig *config = ppImageArguments(argc, argv);
-    if (config == NULL) {
-        psErrorStackPrint(stderr, "Unable to parse command-line arguments.");
-        ppImageCleanup(config, NULL);
-        exit(PS_EXIT_CONFIG_ERROR);
-    }
-
-    ppImageVersionPrint();
-
-    // define recipe options
-    // define the active I/O files
-    ppImageOptions *options = ppImageParseCamera(config);
-    if (options == NULL) {
-        psErrorStackPrint(stderr, "Unable to parse camera.");
-        ppImageCleanup(config, options);
-        exit(PS_EXIT_CONFIG_ERROR);
-    }
-
-    // Image Arithmetic Loop
-    if (!ppImageLoop(config, options)) {
-        psErrorStackPrint(stderr, "Unable to loop over input");
-        ppImageCleanup(config, options);
-        exit(PS_EXIT_SYS_ERROR);
-    }
-
-    psLogMsg("ppImage", PS_LOG_INFO, "Complete ppImage run: %f sec\n", psTimerMark(TIMER_TOTAL));
-
-    // Cleaning up
-    ppImageCleanup(config, options);
-
-    return PS_EXIT_SUCCESS;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImage.h
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImage.h	(revision 29946)
+++ 	(revision )
@@ -1,293 +1,0 @@
-#ifndef PP_IMAGE_H
-#define PP_IMAGE_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>  // for strcasecmp
-#include <unistd.h>   // for unlink
-#include "pslib.h"
-#include "psmodules.h"
-#include "psphot.h"
-#include "psastro.h"
-#include "ppStats.h"
-
-#define RECIPE_NAME "PPIMAGE"           // Name of the recipe to use
-#define TIMER_TOTAL   "PPIMAGE.TOTAL"   // Name of timer for total time
-#define TIMER_DETREND "PPIMAGE.DETREND" // Name of timer for detrend time
-#define TIMER_PHOT    "PPIMAGE.PHOT"    // Name of timer for photometry time
-
-// Options for ppImage processing
-typedef struct {
-    // actions which ppImage should perform
-    bool doMaskBuild;                   // Build internal mask
-    bool doVarianceBuild;               // Build internal variance map
-    bool doMaskBurntool;                // mask potential burntool trails
-    bool doMaskSat;                     // mask saturated pixels
-    bool doMaskLow;                     // mask low pixels
-    bool doMask;                        // Mask bad pixels
-    bool doNonLin;                      // Non-linearity correction
-    bool doOverscan;                    // Overscan subtraction
-    bool doNoiseMap;                    // Bias subtraction
-    bool doBias;                        // Bias subtraction
-    bool doDark;                        // Dark subtraction
-    bool doRemnance;                    // Remnance masking
-    bool doShutter;                     // Shutter correction
-    bool doFlat;                        // Flat-field normalisation
-    bool doPatternRow;                  // Row pattern correction
-    bool doPatternCell;                 // Cell pattern correction
-    bool doFringe;                      // Fringe subtraction
-    bool doPhotom;                      // Source identification and photometry
-    bool doBG;                          // Background subtraction
-    bool doAstromChip;                  // per-chip Astrometry
-    bool doAstromMosaic;                // full-mosaic Astrometry
-    bool doStats;                       // call ppStats on the image
-    bool checkCTE;                      // measure pixel-based variance
-    bool applyParity;                   // Apply Cell parities
-
-  bool doMaskStats;                      // Calculate mask statistics
-  
-    bool doCrosstalkMeasure;            // measure crosstalk signal
-    bool doCrosstalkCorrect;            // apply crosstalk correction
-
-    // output files requested
-    bool BaseFITS;
-    bool BaseMaskFITS;
-    bool BaseVarianceFITS;
-
-    bool ChipFITS;
-    bool ChipMaskFITS;
-    bool ChipVarianceFITS;
-
-    bool FPA1FITS;
-    bool FPA2FITS;
-    bool Bin1FITS;
-    bool Bin1JPEG;
-    bool Bin2FITS;
-    bool Bin2JPEG;
-
-    // make values for abstract concepts of masking
-    psImageMaskType maskValue;          // apply this bit-mask to choose masked bits
-    psImageMaskType markValue;          // apply this bit-mask to choose masked bits
-    psImageMaskType satMask;            // Mask value to give saturated pixels
-    psImageMaskType lowMask;            // Mask value to give bad pixels
-    psImageMaskType flatMask;           // Mask value to give bad flat pixels
-    psImageMaskType darkMask;           // Mask value to give bad dark pixels
-    psImageMaskType blankMask;          // Mask value to give blank pixels
-    psImageMaskType burntoolMask;       // Suspect pixels that fall where a burntool trail is expected.
-    // non-linear correction parameters
-    psDataType nonLinearType;
-    psMetadataItem *nonLinearData;
-    void *nonLinearSource;
-
-    // options for the analysis
-    pmOverscanOptions *overscan;        // Overscan options
-    int burntoolTrails;
-    // binning parameters
-    int xBin1;                          // x-binning, scale 1
-    int yBin1;                          // y-binning, scale 1
-    int xBin2;                          // x-binning, scale 2
-    int yBin2;                          // y-binning, scale 2
-
-    // parameters used by the fringe analysis
-    float fringeRej;                    // Fringe rejection limit
-    int fringeIter;                     // Fringe iterations
-    float fringeKeep;                   // Fringe keep fraction
-
-    // Pattern correction
-    int patternRowOrder;                   // Polynomial order
-    int patternRowIter;                    // Clipping iterations
-    float patternRowRej;                   // Clipping threshold
-    float patternRowThresh;                // Ignore threshold
-    psStatsOptions patternRowMean;         // Statistic for mean
-    psStatsOptions patternRowStdev;        // Statistic for stdev
-    psStatsOptions patternCellBG;          // statistic for background
-    psStatsOptions patternCellMean;        // Statistic for mean
-
-    int remnanceSize;                   // Size for remnance detection
-    float remnanceThresh;               // Threshold for remnance detection
-
-    char *normClass;                    // class to use for per-class normalization
-
-  psU16 maskstat_static;
-  psU16 maskstat_dynamic;
-  psU16 maskstat_magic;
-  psU16 maskstat_advisory;
-  
-} ppImageOptions;
-
-// Cells to be used in the detrend
-typedef struct {
-    pmCell *input;                      // The input cell, to be operated upon
-    pmCell *mask;                       // The bad pixel mask
-    pmCell *bias;                       // The bias correction
-    pmCell *dark;                       // The dark correction
-    pmCell *flat;                       // The flat-field correction
-} ppImageDetrend;
-
-ppImageOptions *ppImageOptionsAlloc(void);
-
-// Determine the processing options
-ppImageOptions *ppImageOptionsParse(pmConfig *config);
-
-// Get the configuration
-pmConfig *ppImageArguments(int argc, char **argv);
-
-// Determine what type of camera, and initialise
-ppImageOptions *ppImageParseCamera(pmConfig *config);
-bool ppImageSetMaskBits (pmConfig *config, ppImageOptions *options);
-
-// apply the cell flips to the input data before analysis
-bool ppImageParityFlip (pmConfig *config, const ppImageOptions *options, const pmFPAview *view, bool native);
-
-// Loop over the input
-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 (pmConfig *config, ppImageOptions *options, pmFPAview *view);
-
-bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options);
-
-//bool ppImageDetrendNonLinear(pmReadout *input, ppImageOptions *options);
-bool ppImageDetrendNonLinear(pmReadout *input, pmFPAview *linearity, pmConfig *config);
-bool ppImageDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem);
-bool ppImageDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem);
-
-bool ppImageDetrendCell(ppImageDetrend *detrend, ppImageOptions *options, pmConfig *config);
-bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options);
-pmReadout* ppImageDetrendSelectFirst(pmCell *cell, char *name, bool doThis);
-
-bool ppImageDetrendFree(pmConfig *config, pmFPAview *view);
-bool ppImageFringeFree(pmConfig *config, pmFPAview *view);
-
-bool ppImageCheckCTE(pmConfig *config, ppImageOptions *options, pmFPAview *view);
-
-bool ppImageBurntoolMask(pmConfig *config, ppImageOptions *options, pmFPAview *view, pmReadout *mask);
-
-bool ppImageDetrendPatternApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, const ppImageOptions *options);
-
-// Record which detrend file was used for the detrending
-bool ppImageDetrendRecord(
-    pmCell *cell,                       // Cell of interest
-    const pmConfig *config,             // Configuration
-    const ppImageOptions *options,      // Processing options
-    const pmFPAview *view               // View to cell
-    );
-
-bool ppImageRebinChip (pmConfig *config, pmFPAview *view, ppImageOptions *options, char *outName);
-
-bool ppImagePhotom(psMetadata *stats, pmConfig *config, pmFPAview *view);
-bool ppImageAstrom(pmConfig *config, psMetadata *stats);
-bool ppImageAddstar(pmConfig *config);
-
-// Subtract background from the chip-mosaicked image
-bool ppImageSubtractBackground(
-    pmConfig *config,                   // Configuration
-    const pmFPAview *view,              // View to chip of interest
-    const ppImageOptions *options       // Processing options
-    );
-
-bool ppImageMosaicChip (pmConfig *config, const ppImageOptions *options, const pmFPAview *view,
-                        const char *outFile, const char *inFile);
-bool ppImageMosaicFPA (pmConfig *config, const ppImageOptions *options,
-                       const char *outFile, const char *inFile);
-
-bool ppImageSetMaskBits (pmConfig *config, ppImageOptions *options);
-
-void ppImageFileCheck (pmConfig *config);
-
-// functions used by ppFocus
-pmConfig *ppFocusArguments(int argc, char **argv);
-ppImageOptions *ppFocusParseCamera (pmConfig *config, int entry);
-bool ppFocusGetFWHM (pmConfig *config, psVector *focus, psVector *fwhm);
-bool ppFocusFitFWHM (pmConfig *config, psVector *focus, psVector *fwhm);
-
-void ppFocusDropCamera (pmConfig *config);
-
-bool ppImageDefineFile (pmConfig *config, pmFPA *input, char *filerule, char *argname, pmFPAfileType fileType, pmDetrendType detrendType);
-
-// write stats to output file
-bool ppImageStatsOutput(pmConfig *config, // Configuration
-                        psMetadata *stats, // Statistics output
-                        const ppImageOptions *options // Options
-    );
-
-
-// measure the crosstalk signal
-bool ppImageMeasureCrosstalk(pmConfig *config, ppImageOptions *options, pmFPAview *view);
-
-// correct the crosstalk signal
-bool ppImageCorrectCrosstalk(pmConfig *config, ppImageOptions *options, pmFPAview *view);
-
-// Measure fringes
-bool ppImageDetrendFringeMeasure(pmReadout *readout, // Readout to measure
-                                 pmCell *fringe, // Fringe cell (each readout is a different component)
-                                 const bool isResidual,
-                                 const ppImageOptions *options // Options
-    );
-
-// Solve the fringe system
-bool ppImageDetrendFringeSolve(pmChip *scienceChip, // Chip with science
-                               const pmChip *refChip, // Chip with reference fringes
-                               const bool isResidual,
-                               const ppImageOptions *options // Options
-    );
-
-// Generate fringe frame
-bool ppImageDetrendFringeGenerate(pmCell *science, // Science cell
-                                  pmCell *fringes, // Fringe cell, one readout per fringe component
-                                  const ppImageOptions *options // Options
-    );
-
-
-bool ppImageDetrendFringeApply (pmConfig *config, // config
-                                pmChip *chip, // science chip
-                                const pmFPAview *inputView, // current view
-                                const ppImageOptions *options // options
-    );
-
-/// Return short version information
-psString ppImageVersion(void);
-
-/// Return software source
-psString ppImageSource(void);
-
-/// Return long version information
-psString ppImageVersionLong(void);
-
-/// Populate the header with version information for all dependencies
-bool ppImageVersionHeader(psMetadata *metadata ///< Header to populate
-    );
-
-/// Print version information
-void ppImageVersionPrint(void);
-
-
-// calculate stats, including MD5
-bool ppImagePixelStats(pmConfig *config,// Configuration
-                       psMetadata *stats, // Statistics output
-                       const ppImageOptions *options, // Options
-                       const pmFPAview *inputView // View to data
-    );
-
-// Calculate Mask statistics
-bool ppImageMaskStats(pmConfig *config, pmFPAview *view, psMetadata *stats);
-
-// calculate stats from headers and concepts
-bool ppImageMetadataStats(pmConfig *config, // Configuration
-                          psMetadata *stats, // Statistics output
-                          const ppImageOptions *options // Options
-    );
-
-void ppImageFileCheck(pmConfig *config);
-
-/// Dump memory summary to text file
-void ppImageMemoryDump(const char *description);
-
-#endif
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageAddstar.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageAddstar.c	(revision 29946)
+++ 	(revision )
@@ -1,120 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-bool setFilename (pmFPAfile *file, pmFPAview *view);
-bool addstarFile (char *addstarCommand, char *filename);
-
-bool ppImageAddstar (pmConfig *config) {
-
-    bool status;
-    pmChip *chip;
-    pmCell *cell;
-    pmReadout *readout;
-
-    // select recipe options supplied on command line
-    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, RECIPE_NAME);
-
-    // find a pmFPAfile PSASTRO.OUTPUT
-    pmFPAfile *file = psMetadataLookupPtr (&status, config->files, "PSASTRO.OUTPUT");
-    if (!status) {
-        psError (PS_ERR_IO, true, "no PSASTRO.OUTPUT file defined");
-        return false;
-    }
-
-    // find the addstar command: %s is replaced with name of output file
-    char *addstarCommand = psMetadataLookupStr (&status, recipe, "ADDSTAR.COMMAND");
-
-    pmFPAview *view = pmFPAviewAlloc (0);
-    if (file->fileLevel == PM_FPA_LEVEL_CHIP) {
-        // call addstar on this file
-        setFilename (file, view);
-        addstarFile (addstarCommand, file->filename);
-        return true;
-    }
-
-    while ((chip = pmFPAviewNextChip (view, file->fpa, 1)) != NULL) {
-        psLogMsg ("ppImageAddstar", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
-        if (!chip->process || !chip->file_exists) { continue; }
-
-        if (file->fileLevel == PM_FPA_LEVEL_CHIP) {
-            // call addstar on this file
-            setFilename (file, view);
-            addstarFile (addstarCommand, file->filename);
-            continue;
-        }
-
-        while ((cell = pmFPAviewNextCell (view, file->fpa, 1)) != NULL) {
-            psLogMsg ("ppImageAddstar", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-            if (! cell->process || ! cell->file_exists) { continue; }
-
-            if (file->fileLevel == PM_FPA_LEVEL_CELL) {
-                // call addstar on this file
-                setFilename (file, view);
-                addstarFile (addstarCommand, file->filename);
-                continue;
-            }
-
-            // process each of the readouts
-            while ((readout = pmFPAviewNextReadout (view, file->fpa, 1)) != NULL) {
-                if (! readout->data_exists) { continue; }
-
-                if (file->fileLevel == PM_FPA_LEVEL_READOUT) {
-                    // call addstar on this file
-                    setFilename (file, view);
-                    addstarFile (addstarCommand, file->filename);
-                    continue;
-                } else {
-                    psError (PS_ERR_IO, true, "inconsistent fileLevel for %s: %d\n", file->name, file->fileLevel);
-                    return false;
-                }
-            }
-        }
-    }
-    return true;
-}
-
-bool setFilename (pmFPAfile *file, pmFPAview *view) {
-
-    // determine the file name
-    // free a name allocated earlier
-    psFree (file->filename);
-    file->filename = pmFPAfileNameFromRule (file->filerule, file, view);
-    if (file->filename == NULL) {
-        psError(PS_ERR_IO, true, "Filename is NULL");
-        return false;
-    }
-
-    // indirect filenames are not allowed for output
-    if (!strcasecmp (file->filename, "@FILES")) {
-        psError(PS_ERR_IO, true, "indirect filenames are not allowed for output : %s\n", file->name);
-        return false;
-    }
-    if (!strcasecmp (file->filename, "@DETDB")) {
-        psError(PS_ERR_IO, true, "detrend db filenames are not allowed for output : %s\n", file->name);
-        return false;
-    }
-    return true;
-}
-
-bool addstarFile (char *addstarCommand, char *filename) {
-
-    bool status;
-    char *addstarLine = psStringCopy(addstarCommand);
-    psStringSubstitute(&addstarCommand, filename, "%s");
-
-    // catch addstar stderr/stdout and do what?
-    psIOBuffer *buffer = psIOBufferAlloc (512);
-    psPipe *pipe = psPipeOpen (addstarLine);
-    status = psIOBufferReadEmpty (buffer, 100, pipe->fd_stdout);
-    if (!status) {
-        psError (PS_ERR_IO, false, "detselect is not responding");
-    }
-    psFree (addstarLine);
-    psFree (buffer);
-    psPipeClose (pipe);
-    psFree (pipe);
-    return status;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageArguments.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageArguments.c	(revision 29946)
+++ 	(revision )
@@ -1,173 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-static void usage (void) {
-    fprintf(stderr, "USAGE: ppImage [-file INPUT.fits] [-list INPUT.txt] OUTPUT\n\n");
-    fprintf(stderr, "Optional arguments:\n");
-    fprintf(stderr, "\t-stats STATS.mdc: Output statistics into STATS.mdc\n");
-    fprintf(stderr, "\t-isfringe: The input image contains fringe data.\n");
-    fprintf(stderr, "\t-isdark: The input image contains dark data.\n");
-    fprintf(stderr, "\t-usemask MASKVAL: Use this mask value (override recipe).\n");
-    fprintf(stderr, "\t-chip CHIPNUM: Only process this chip number.\n");
-    fprintf(stderr, "\t-norm VALUE: Divide through by this value when done.\n");
-    fprintf(stderr, "\t-normlist file.mdc: normalizations by class_id.\n");
-    fprintf(stderr, "\t-video: process video cells\n");
-    fprintf(stderr, "\n");
-    fprintf(stderr, "Input options (single file / file list):\n");
-    fprintf(stderr, "\t-noisemap/-noisemaplist: Noise Map image.\n");
-    fprintf(stderr, "\t-bias/-biaslist: Bias image.\n");
-    fprintf(stderr, "\t-dark/-darklist: Dark image.\n");
-    fprintf(stderr, "\t-shutter/-shutterlist: Shutter image.\n");
-    fprintf(stderr, "\t-flat/-flatlist: Flat image.\n");
-    fprintf(stderr, "\t-mask/-masklist: Mask image.\n");
-    fprintf(stderr, "\t-fringe/-fringelist: Fringe image and data.\n");
-    fprintf(stderr, "\t-linearity/-linearlist: linearity correction file.\n");
-    fprintf(stderr, "\n");
-    exit (2);
-}
-
-pmConfig *ppImageArguments(int argc, char **argv)
-{
-    int argnum;                         // Argument number of interest
-
-    if (argc == 1) {
-        usage();
-    }
-
-    if (psArgumentGet (argc, argv, "-version")) {
-        psString version;
-        version = ppImageVersionLong();   fprintf (stdout, "%s\n", version); psFree (version);
-        version = ppStatsVersionLong();   fprintf (stdout, "%s\n", version); psFree (version);
-        version = psphotVersionLong();    fprintf (stdout, "%s\n", version); psFree (version);
-        version = psastroVersionLong();   fprintf (stdout, "%s\n", version); psFree (version);
-        version = psModulesVersionLong(); fprintf (stdout, "%s\n", version); psFree (version);
-        version = psLibVersionLong();     fprintf (stdout, "%s\n", version); psFree (version);
-        exit (0);
-    }
-
-    // load the site-wide configuration information
-    pmConfig *config = pmConfigRead(&argc, argv, RECIPE_NAME);
-    if (config == NULL) {
-        psErrorStackPrint(stderr, "Can't find site configuration!\n");
-        exit(EXIT_FAILURE);
-    }
-
-    // save the following additional recipe values based on command-line options
-    // these options override the PPIMAGE recipe values loaded from recipe files
-    psMetadata *options = pmConfigRecipeOptions (config, RECIPE_NAME);
-
-    // 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);
-
-    if ((argnum = psArgumentGet(argc, argv, "-stats"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "STATS", PS_META_REPLACE,
-                         "Filename for summary statistics", argv[argnum]);
-        psArgumentRemove(argnum, &argc, argv);
-    }
-
-    if ((argnum = psArgumentGet(argc, argv, "-isfringe"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "INPUT_IS_FRINGE", PS_META_REPLACE,
-                          "Input is fringe image", true);
-    }
-    if ((argnum = psArgumentGet(argc, argv, "-isdark"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "INPUT_IS_DARK", PS_META_REPLACE,
-                          "Input is dark image", true);
-    }
-    
-    if ((argnum = psArgumentGet(argc, argv, "-video"))) {
-      psArgumentRemove(argnum, &argc, argv);
-      psMetadataAddBool(config->arguments, PS_LIST_TAIL, "PROCESS_VIDEO", PS_META_REPLACE, "process video cells", true);
-    }
-
-    if ((argnum = psArgumentGet(argc, argv, "-visual"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        pmVisualSetVisual(true);
-    }
-
-    // Number of threads
-    if ((argnum = psArgumentGet(argc, argv, "-threads"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        int nThreads = atoi(argv[argnum]);
-        psMetadataAddS32(config->arguments, PS_LIST_TAIL, "NTHREADS", 0, "number of warp threads", nThreads);
-        psArgumentRemove(argnum, &argc, argv);
-
-        // create the thread pool with number of desired threads, supplying our thread launcher function
-        // XXX need to determine the number of threads from the config data
-        psThreadPoolInit (nThreads);
-    }
-
-    // the following options override the PPIMAGE recipe options
-
-    // recipe option: -usemask : override MASK setting in recipe
-    if ((argnum = psArgumentGet(argc, argv, "-usemask"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        psMetadataAddBool(options, PS_LIST_TAIL, "MASK", PS_META_REPLACE, "", true);
-        psArgumentRemove(argnum, &argc, argv);
-    }
-
-    // XXX add other PPIMAGE recipe options here
-
-    // the input file is a required argument; if not found, we will exit
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "INPUT", "-file", "-list");
-
-    // 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, "NOISEMAP", "-noisemap", "-noisemaplist");
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "BIAS", "-bias", "-biaslist");
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "DARK", "-dark", "-darklist");
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "SHUTTER", "-shutter", "-shutterlist");
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "FLAT", "-flat", "-flatlist");
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "MASK", "-mask", "-masklist");
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "FRINGE", "-fringe", "-fringelist");
-    pmConfigFileSetsMD (config->arguments, &argc, argv, "LINEARITY", "-linearity", "-linearlist");
-
-    // chip selection is used to limit chips to be processed
-    if ((argnum = psArgumentGet (argc, argv, "-chip"))) {
-        psArgumentRemove (argnum, &argc, argv);
-        psMetadataAddStr (config->arguments, PS_LIST_TAIL, "CHIP_SELECTIONS", PS_DATA_STRING, "", argv[argnum]);
-        psArgumentRemove (argnum, &argc, argv);
-    }
-
-    // Optional normalization factor
-    if ((argnum = psArgumentGet(argc, argv, "-norm"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        float norm = atof(argv[argnum]);
-        psMetadataAddF32(config->arguments, PS_LIST_TAIL, "NORMALIZATION", 0,
-                         "Normalisation to apply", norm);
-        psArgumentRemove(argnum, &argc, argv);
-    }
-
-    // Optional per-class normalization table
-    if ((argnum = psArgumentGet(argc, argv, "-normlist"))) {
-        psArgumentRemove(argnum, &argc, argv);
-
-        unsigned int nFail = 0;
-        psMetadata *normlist = psMetadataConfigRead (NULL, &nFail, argv[argnum], false);
-        // XXX allow this file to be in nebulous?
-
-        psMetadataAddMetadata(config->arguments, PS_LIST_TAIL, "NORMALIZATION.TABLE", 0, "Normalization to apply", normlist);
-        psFree (normlist);
-        psArgumentRemove(argnum, &argc, argv);
-    }
-
-    if ((argnum = psArgumentGet(argc, argv, "-dumpconfig"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "DUMP_CONFIG", PS_META_REPLACE,
-                         "Filename for configuration dump", argv[argnum]);
-        psArgumentRemove(argnum, &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: anches/haf_branches/videophot2010/ppImage/src/ppImageAstrom.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageAstrom.c	(revision 29946)
+++ 	(revision )
@@ -1,66 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-// this function is mostly equivalent to the top-level of psastro, with some
-// modifications since the data has already been loaded.
-bool ppImageAstrom (pmConfig *config, psMetadata *stats) {
-
-    bool status;
-
-    // select recipe options supplied on command line
-    // XXX move these options to the "PSASTRO" recipe?
-    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);
-
-    // find or define a pmFPAfile PSPHOT.INPUT
-    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSASTRO.INPUT");
-    PS_ASSERT (input, false);
-
-    ppImageMemoryDump("astrom");
-
-    // convert the output sources created by psphot into astrometry objects
-    if (!psastroConvertFPA (input->fpa, recipe)) {
-        psError (PSASTRO_ERR_UNKNOWN, false, "error reading input data\n");
-        return false;
-    }
-
-    if (!psastroAnalysis(config, stats)) {
-        psError (PSASTRO_ERR_UNKNOWN, false, "failure in psastro analysis\n");
-        return false;
-    }
-
-    // deactivate the psastro files, reactive when needed
-    pmFPAfileActivate (config->files, false, NULL);
-    pmFPAfileActivate (config->files, true, "PSASTRO.OUTPUT");
-
-    // loop over all chips and perform IO needed
-    pmChip *chip = NULL;
-    pmFPAview *view = pmFPAviewAlloc(0);// View for level of interest
-    while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) {
-        psLogMsg ("ppImageLoop", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
-
-        ppImageMemoryDump("astrom");
-
-        // Output and Close at Chip level
-        if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-            psFree(view);
-            return false;
-        }
-    }
-
-    // Output and Close FPA
-    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-        psFree(view);
-        return false;
-    }
-
-    // deactivate the PSASTRO files, re-active all else
-    // XXX do we need a way to activate / deactivate other groups?
-    pmFPAfileActivate (config->files, true, NULL);
-    pmFPAfileActivate (config->files, false, "PSASTRO.OUTPUT");
-
-    psFree(view);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageBurntoolMask.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageBurntoolMask.c	(revision 29946)
+++ 	(revision )
@@ -1,96 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define PPIMAGE_BURNTOOL_DEBUG 0
-
-#include "ppImage.h"
-
-bool ppImageBurntoolMask (pmConfig *config, ppImageOptions *options, pmFPAview *view,pmReadout *mask) {
-  bool status = true;
-  int burntool_cell;
-  /* Find input filename */
-  pmFPAfile *inputFile = psMetadataLookupPtr(&status , config->files, "PPIMAGE.INPUT");
-  if (!status) {
-    psError(PS_ERR_IO,false, "Unable to identify inputFile");
-    return(false);
-  }
-  psFits *fits = inputFile->fits;
-
-  /* Read input header, and find the burntool data table. */
-  if (!psFitsMoveExtName(fits,"burntool_areas")) {
-    psError(PS_ERR_IO,false, "Unable to find extension burntool_areas");
-    return(false);
-  }
-  long Nrows = psFitsTableSize(fits);
-
-  long row = 0;
-
-  psLogMsg ("ppImageBurntoolMask", 4, "Inside burntool mask %ld", Nrows);
-
-  /* Redirects and Memory juggling. */
-  view->readout = 0;
-  psImage *image = mask->mask;
-
-
-  /* Set the maskValue from the recipes. */
-  psImageMaskType maskValue = options->burntoolMask;
-#if PPIMAGE_BURNTOOL_DEBUG
-  psLogMsg("ppImageBurntoolMask", 4, "Status: %ld %d\n",Nrows,maskValue);
-#endif
-
-  burntool_cell = view->cell;
-  burntool_cell = (view->cell % 8) * 8 + (view->cell - (view->cell % 8)) / 8;
-  psLogMsg("ppImageBurntoolMask", 4, "Cell mapping: %d %d %d\n",view->cell,burntool_cell,-1);
-  for (row = 0; row < Nrows; row++) {
-    psMetadata *rowMD = psFitsReadTableRow(fits,row);
-
-    if (psMetadataLookupS32(&status,rowMD,"cell") == burntool_cell) {
-      if (((options->burntoolTrails & 0x01)&&(psMetadataLookupS32(&status,rowMD,"func") == 4))||
-          (((options->burntoolTrails & 0x02)&&(psMetadataLookupS32(&status,rowMD,"up") == 1))||
-           ((options->burntoolTrails & 0x04)&&(psMetadataLookupS32(&status,rowMD,"up") == 0)))) {
-        /*       If the fit fails, burntool reports zero here.  This
-                 signifies that it expected to see a trail (else why
-                 fit) but did not find it when it attempted to
-                 correct. */
-#if PPIMAGE_BURNTOOL_DEBUG
-        psLogMsg ("ppImageBurntoolMask", 4, "Masking! %d (%d %d %d) %d %d",
-                  psMetadataLookupS32(&status,rowMD,"cell"),
-                  ((options->burntoolTrails & 0x0001)&&(psMetadataLookupS32(&status,rowMD,"nfit") == 0)),
-                  ((options->burntoolTrails & 0x02)&&(psMetadataLookupS32(&status,rowMD,"up") == 1)),
-                  ((options->burntoolTrails & 0x04)&&(psMetadataLookupS32(&status,rowMD,"up") == 0)),
-                  options->burntoolTrails,
-                  maskValue
-                  );
-#endif
-        for (int i = psMetadataLookupS32(&status,rowMD,"sxfit");
-             i <= psMetadataLookupS32(&status,rowMD,"exfit");
-             i++) {
-
-          if (psMetadataLookupS32(&status,rowMD,"up") == 0) {
-            for (int j = 0; j <= psMetadataLookupS32(&status,rowMD,"y1p"); j++) {
-#if PPIMAGE_BURNTOOL_DEBUG
-              psLogMsg("ppImageBurntoolMask", 4, "Noisy!: %d %d %d %d\n",
-                       i,j,image->data.PS_TYPE_IMAGE_MASK_DATA[j][i],maskValue);
-#endif
-              image->data.PS_TYPE_IMAGE_MASK_DATA[j][i] |= maskValue;
-            }
-          }
-          else {
-            for (int j = psMetadataLookupS32(&status,rowMD,"y1m"); j < image->numRows ; j++) {
-#if PPIMAGE_BURNTOOL_DEBUG
-              psLogMsg("ppImageBurntoolMask", 4, "Noisy!: %d %d %d %d\n",
-                       i,j,image->data.PS_TYPE_IMAGE_MASK_DATA[j][i],maskValue);
-#endif
-              image->data.PS_TYPE_IMAGE_MASK_DATA[j][i] |= maskValue;
-            }
-          }
-        }
-
-      }
-    }
-    psFree(rowMD);
-  }
-
-  return(status);
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageCheckCTE.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageCheckCTE.c	(revision 29946)
+++ 	(revision )
@@ -1,109 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-// XXX I originally coded this to create a new pmFPAfile, but in retrospect it makes more sense
-// to treat this function as an operation on the input image
-
-// XXX make the choice of stats optional
-bool ppImageCheckCTE(pmConfig *config, ppImageOptions *options, pmFPAview *view)
-{
-    bool status;
-
-    // this step is complete optional.
-    if (!options->checkCTE) {
-        return true;
-    }
-
-    // add recipe options supplied on command line
-    psMetadata *recipe  = psMetadataLookupPtr(&status, config->recipes, RECIPE_NAME);
-
-    // find the currently selected readout
-    pmReadout *inReadout = pmFPAfileThisReadout(config->files, view, "PPIMAGE.INPUT");
-
-    psImage *image    = inReadout->image;
-    psImage *mask     = inReadout->mask;
-    // psImage *variance = inReadout->variance;
-
-    // I have the fine image size, I know the binning factor, determine the ruff image size
-    psImageBinning *binning = psImageBinningAlloc();
-    binning->nXfine = image->numCols;
-    binning->nYfine = image->numRows;
-    binning->nXbin  = psMetadataLookupS32 (&status, recipe, "CTE.XBIN");
-    binning->nYbin  = psMetadataLookupS32 (&status, recipe, "CTE.YBIN");
-
-    psImageBinningSetRuffSize(binning, PS_IMAGE_BINNING_CENTER);
-    psImageBinningSetSkip(binning, image);
-
-    psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN);
-    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);
-    psImageBackground (stats, NULL, image, mask, 0xffff, rng);
-    float cellMedian = stats->robustMedian;
-    psFree (stats);
-
-    // stats = psStatsAlloc (PS_STAT_SAMPLE_STDEV);
-    // psStats *statsDefaults = psStatsAlloc (PS_STAT_SAMPLE_STDEV);
-
-    stats = psStatsAlloc (PS_STAT_ROBUST_STDEV);
-    psStats *statsDefaults = psStatsAlloc (PS_STAT_ROBUST_STDEV);
-
-    // measure median and variance for subimages
-    psRegion ruffRegion = {0,0,0,0};
-    psRegion fineRegion = {0,0,0,0};
-    for (int iy = 0; iy < binning->nYruff; iy++) {
-        for (int ix = 0; ix < binning->nXruff; ix++) {
-
-            // convert the ruff grid cell to the equivalent fine grid cell
-            ruffRegion = psRegionSet (ix, ix + 1, iy, iy + 1);
-            fineRegion = psImageBinningSetFineRegion (binning, ruffRegion);
-            fineRegion = psRegionForImage (image, fineRegion);
-            if (fineRegion.x0 >= image->numCols) continue;
-	    if (fineRegion.y0 >= image->numRows) continue;
-
-            psImage *subset  = psImageSubset (image, fineRegion);
-            if (!subset->numCols || !subset->numRows) {
-                psFree (subset);
-                continue;
-            }
-            psImage *submask = NULL;
-            if (mask) {
-                submask = psImageSubset (mask, fineRegion);
-            }
-
-            // reset the default values
-            statsDefaults->tmpData = stats->tmpData; // XXX this is fairly hackish: tmpData is internal storage for stats; the assign drops the reference...
-            *stats = *statsDefaults;
-            statsDefaults->tmpData = NULL;
-
-            psImageStats (stats, subset, submask, 0xffff);
-
-	    // XXX need to apply the gain as well
-	    float normVariance = PS_SQR(stats->robustStdev) / cellMedian;
-	    // float normVariance = PS_SQR(stats->sampleStdev) / cellMedian;
-	    // if (!isfinite(normVariance)) fprintf (stderr, "** normVariance is nan **\n");
-
-	    // apply resulting value to the input pixels
-	    for (int jy = fineRegion.y0; jy < fineRegion.y1; jy++) {
-	      if (jy < 0) continue;
-	      if (jy >= image->numRows) continue;
-	      for (int jx = fineRegion.x0; jx < fineRegion.x1; jx++) {
-		if (jx < 0) continue;
-		if (jx >= image->numCols) continue;
-		image->data.F32[jy][jx] = normVariance;
-	      }
-	    }
-
-            psFree (subset);
-            psFree (submask);
-        }
-    }
-
-    psFree (rng);
-    psFree (binning);
-    psFree (stats);
-    psFree (statsDefaults);
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageCheckCTE.v1.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageCheckCTE.v1.c	(revision 29946)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageCheckCTE(pmConfig *config, ppImageOptions *options, pmFPAview *view)
-{
-    bool status;
-
-    // this step is complete optional.
-    if (!options->checkCTE) {
-        return true;
-    }
-
-    // add recipe options supplied on command line
-    psMetadata *recipe  = psMetadataLookupPtr(&status, config->recipes, RECIPE_NAME);
-
-    // find the currently selected readout
-    pmReadout *inReadout = pmFPAfileThisReadout(config->files, view, "PPIMAGE.INPUT");
-
-    psImage *image    = inReadout->image;
-    psImage *mask     = inReadout->mask;
-    // psImage *variance = inReadout->variance;
-
-    // I have the fine image size, I know the binning factor, determine the ruff image size
-    psImageBinning *binning = psImageBinningAlloc();
-    binning->nXfine = image->numCols;
-    binning->nYfine = image->numRows;
-    binning->nXbin  = psMetadataLookupS32 (&status, recipe, "CTE.XBIN");
-    binning->nYbin  = psMetadataLookupS32 (&status, recipe, "CTE.YBIN");
-
-    psImageBinningSetRuffSize(binning, PS_IMAGE_BINNING_CENTER);
-    psImageBinningSetSkip(binning, image);
-
-    pmCell *inCell  = pmFPAfileThisCell (config->files, view, "PPIMAGE.INPUT");
-    pmCell *outCell = pmFPAfileThisCell (config->files, view, "PPIMAGE.CTEMAP");
-    if (!pmCellCopyStructure(outCell, inCell, binning->nXbin, binning->nYbin)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to copy cell structure.");
-        return false;
-    }
-
-    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPIMAGE.CTEMAP");
-    psImage *output = outRO->image;
-
-    // Don't care about the bias: get rid of it, if present
-    psFree(outRO->bias);
-    outRO->bias = psListAlloc(NULL);
-    psMetadataItem *biassec = psMetadataLookup(outCell->concepts, "CELL.BIASSEC");
-    psFree(biassec->data.V);
-    biassec->data.V = psListAlloc(NULL);
-
-    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
-    psStats *statsDefaults = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
-
-    // measure median and variance for subimages
-    psRegion ruffRegion = {0,0,0,0};
-    psRegion fineRegion = {0,0,0,0};
-    for (int iy = 0; iy < output->numRows; iy++) {
-        for (int ix = 0; ix < output->numCols; ix++) {
-
-            // convert the ruff grid cell to the equivalent fine grid cell
-            ruffRegion = psRegionSet (ix, ix + 1, iy, iy + 1);
-            fineRegion = psImageBinningSetFineRegion (binning, ruffRegion);
-            fineRegion = psRegionForImage (image, fineRegion);
-            if (fineRegion.x0 >= image->numCols || fineRegion.x1 >= image->numCols ||
-                fineRegion.y0 >= image->numRows || fineRegion.y1 >= image->numRows) {
-                continue;
-            }
-
-            psImage *subset  = psImageSubset (image, fineRegion);
-            if (!subset->numCols || !subset->numRows) {
-                psFree (subset);
-                continue;
-            }
-            psImage *submask = NULL;
-            if (mask) {
-                submask = psImageSubset (mask, fineRegion);
-            }
-
-            // reset the default values
-            statsDefaults->tmpData = stats->tmpData; // XXX this is fairly hackish: tmpData is internal storage for stats; the assign drops the reference...
-            *stats = *statsDefaults;
-            statsDefaults->tmpData = NULL;
-
-            psImageStats (stats, subset, submask, 0);
-
-            // XXX need to apply the gain as well
-            output->data.F32[iy][ix] = PS_SQR(stats->sampleStdev) / stats->sampleMedian;
-
-            psFree (subset);
-            psFree (submask);
-        }
-    }
-
-    psFree (binning);
-    psFree (stats);
-    psFree (statsDefaults);
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageCleanup.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageCleanup.c	(revision 29946)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-void ppImageCleanup (pmConfig *config, ppImageOptions *options)
-{
-    if (psErrorCodeLast() != PS_ERR_NONE) {
-        pmFPAfileFreeSetStrict(false);
-    }
-
-    // Free memory used by ppImage
-    psFree(options);
-    psFree(config);
-
-    // Free memory used by psModules
-    pmSourceFitSetDone ();
-    pmConceptsDone();
-    pmConfigDone();
-    pmModelClassCleanup();
-    pmVisualCleanup ();
-
-    // Free memory used by psLib
-    psLibFinalize();
-
-    // psMemBlock **memblocks;
-    // int Nleaks = psMemCheckLeaks (0, &memblocks, stderr, false);
-    // fprintf (stderr, "Found %d leaks at %s\n", Nleaks, "ppImage");
-
-    // fprintf(stderr, "Found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "ppImage");
-    psLogMsg("ppImage", PS_LOG_INFO, "Memory leaks: %d\n", psMemCheckLeaks(0, NULL, stdout, false));
-
-    return;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageCorrectCrosstalk.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageCorrectCrosstalk.c	(revision 29946)
+++ 	(revision )
@@ -1,18 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-#define ESCAPE(MESSAGE) { \
-  psError(PS_ERR_UNKNOWN, false, MESSAGE); \
-  psFree(view); \
-  return false; \
-}
-
-// For the moment, this implementation is VERY GPC-specific
-
-bool ppImageCorrectCrosstalk(pmConfig *config, ppImageOptions *options, pmFPAview *view)
-{
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageDefineFile.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageDefineFile.c	(revision 29946)
+++ 	(revision )
@@ -1,56 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-bool ppImageDefineFile(pmConfig *config, pmFPA *input, char *filerule, char *argname,
-                       pmFPAfileType fileType, pmDetrendType detrendType)
-{
-    bool status;
-    pmFPAfile *file = NULL;             // File to be defined
-
-    if (!file) {
-        // look for the file on the argument list
-        file = pmFPAfileDefineFromArgs(&status, config, filerule, argname);
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition ARG LIST");
-            return false;
-        }
-    }
-    if (!file) {
-        // look for the file on the RUN metadata
-        file = pmFPAfileDefineFromRun(&status, NULL, config, filerule);
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition RUN");
-            return false;
-        }
-    }
-    if (!file) {
-        // look for the file in the camera config table
-        file = pmFPAfileDefineFromConf(&status, config, filerule);
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition CONFIG");
-            return false;
-        }
-    }
-    if (!file) {
-        // look for the file to be loaded from the detrend database
-        file = pmFPAfileDefineFromDetDB(&status, config, filerule, input, detrendType);
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to load file definition DETREND");
-            return false;
-        }
-    }
-
-    if (!file) {
-        return false;
-    }
-
-    if (file->type != fileType) {
-        psError(PS_ERR_IO, true, "%s is not of type %s", filerule, pmFPAfileStringFromType(fileType));
-        return false;
-    }
-    return true;
-}
-
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageDetrendFree.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageDetrendFree.c	(revision 29946)
+++ 	(revision )
@@ -1,72 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-// list of the detrend types to free
-static char *detrendTypes[] = {
-    "PPIMAGE.MASK",
-    "PPIMAGE.NOISEMAP",
-    "PPIMAGE.BIAS",
-    "PPIMAGE.DARK",
-    "PPIMAGE.FLAT",
-    "PPIMAGE.SHUTTER",
-    "PPIMAGE.LINEARITY",
-    NULL
-};
-
-bool ppImageDetrendFree (pmConfig *config, pmFPAview *view) {
-
-    bool status;
-
-    for (int i = 0; detrendTypes[i] != NULL; i++) {
-
-	pmFPAfile *file = psMetadataLookupPtr(&status, config->files, detrendTypes[i]); // File of interest
-	psTrace("pmFPAfileFree",1,"Working on %s\n",detrendTypes[i]);
-	if (!file) continue; // not all detrends are used in any given run
-
-	// this only returns false on a failure.  if we are not ready to write or close, it is not an error
-	if (!pmFPAfileWrite (file, view, config)) {
-	    psError(PS_ERR_IO, false, "failed to WRITE %s", file->name);
-	    return false;
-	}
-	if (!pmFPAfileClose(file, view)) {
-	    psError(PS_ERR_IO, false, "failed to CLOSE for %s", file->name);
-	    return false;
-	}
-	if (!pmFPAfileFreeData(file, view)) {
-	    if (!psMetadataRemoveKey(config->files, file->name)) {
-		psError(PS_ERR_IO, false, "failed to remove %s in FPA_AFTER block", file->name);
-		return false;
-	    }
-	}
-    }
-    return true;
-}
-
-bool ppImageFringeFree (pmConfig *config, pmFPAview *view) {
-
-    bool status;
-
-    pmFPAfile *file = psMetadataLookupPtr(&status, config->files, "PPIMAGE.FRINGE"); // File of interest
-    if (!file) return true;
-
-    // this only returns false on a failure.  if we are not ready to write or close, it is not an error
-    if (!pmFPAfileWrite (file, view, config)) {
-	psError(PS_ERR_IO, false, "failed to WRITE %s", file->name);
-	return false;
-    }
-    if (!pmFPAfileClose(file, view)) {
-	psError(PS_ERR_IO, false, "failed to CLOSE for %s", file->name);
-	return false;
-    }
-    if (!pmFPAfileFreeData(file, view)) {
-	if (!psMetadataRemoveKey(config->files, file->name)) {
-	    psError(PS_ERR_IO, false, "failed to remove %s in FPA_AFTER block", file->name);
-	    return false;
-	}
-    }
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageDetrendFringe.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageDetrendFringe.c	(revision 29946)
+++ 	(revision )
@@ -1,390 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageDetrendFringeMeasure(pmReadout *readout, pmCell *fringe, const bool isResidual, const ppImageOptions *options)
-{
-    PS_ASSERT_PTR_NON_NULL(readout, false);
-    PS_ASSERT_PTR_NON_NULL(fringe, false);
-    PS_ASSERT_PTR_NON_NULL(options, false);
-
-    // Reference fringe measurements (stored on the reference cell->analysis)
-    psArray *references = psMemIncrRefCounter(psMetadataLookupPtr(NULL, fringe->analysis, "FRINGE.MEASUREMENTS"));
-    if (!references) {
-        psError(PS_ERR_IO, false, "Unable to find fringe references.\n");
-        return false;
-    }
-
-    pmFringeStats *reference = references->data[0]; // Take the first as representative
-    pmFringeRegions *regions = reference->regions; // Regions to measure
-    pmFringeStats *measurements = pmFringeStatsMeasure(regions, readout, options->maskValue); // Fringe stats
-
-    // Normalise measurements by the exposure time
-    bool mdok;                          // Status of MD lookup
-    float expTime = psMetadataLookupF32(&mdok, readout->parent->concepts, "CELL.EXPOSURE"); // Exp. time
-    if (!mdok || !isfinite(expTime)) {
-        psError(PS_ERR_UNKNOWN, false, "CELL.EXPOSURE is not set for --- can't normalise fringes\n");
-        psFree(measurements);
-        return false;
-    }
-    if (expTime == 0) {
-        psWarning("Exposure time is zero --- are you sure you want fringe subtraction?\n");
-        expTime = 1.0;
-    }
-    // normalize by exposure time : NOTE df is 1/sigma
-    psBinaryOp(measurements->f, measurements->f, "*", psScalarAlloc(1.0 / expTime, PS_TYPE_F32));
-    psBinaryOp(measurements->df, measurements->df, "*", psScalarAlloc(expTime, PS_TYPE_F32));
-
-    char *scienceFringes = NULL;
-    if (isResidual) {
-        scienceFringes = psStringCopy ("FRINGE.RESIDUALS");
-    } else {
-        scienceFringes = psStringCopy ("FRINGE.MEASUREMENTS");
-    }
-
-    // Science fringe measurements
-    pmFringeStats *previous = psMetadataLookupPtr(NULL, readout->parent->analysis, scienceFringes);
-    if (previous) {
-        // Multiple readouts: concatenate
-        psArray *concatenate = psArrayAlloc(2); // Array to hold fringes
-
-        // Concatenate science measurements
-        concatenate->data[0] = previous;
-        concatenate->data[1] = measurements;
-        pmFringeStats *new = pmFringeStatsConcatenate(concatenate, NULL, NULL); // New measurements
-        psFree(measurements);
-        measurements = new;
-
-        // Concatenate reference measurements (duplication, so the science and reference line up)
-        for (int i = 0; i < references->n; i++) {
-            concatenate->data[0] = concatenate->data[1] = references->data[i];
-            pmFringeStats *refNew = pmFringeStatsConcatenate(concatenate, NULL, NULL);
-            psFree(references->data[i]);
-            references->data[i] = refNew;
-        }
-        concatenate->data[0] = concatenate->data[1] = NULL;
-        psFree(concatenate);
-    }
-
-    psMetadataAdd(readout->parent->analysis, PS_LIST_TAIL, scienceFringes, PS_DATA_UNKNOWN | PS_META_REPLACE, "Fringe measurements", measurements);
-    psFree(measurements);
-    psFree(scienceFringes);
-    psFree(references);
-
-    return true;
-}
-
-
-// Pull the fringes out of the cell analysis FRINGE.MEASUREMENTS for a chip
-// XXX need some error checks
-static psArray *getFringes(const pmChip *chip, const char *source)
-{
-    psArray *cells = chip->cells;       // Component cells
-    psArray *fringes = psArrayAlloc(cells->n); // Fringes, to return
-    int video_cell_zero = 0;
-
-    for (int i = 0; i < cells->n; i++) {
-        fringes->data[i] = NULL;
-
-        pmCell *cell = cells->data[i];  // Cell of interest
-
-        psTrace("psModules.detrend",7,"Readouts: Cell %d chip: %ld\n",i,cell->readouts->n);
-        // XXX for now, skip the video cells (cell->readouts->n > 1)
-        // CZW: This mess creates a fake set of fringe stats by stealing the previous one.
-        // We let the fitting code know that this is all lies by scaling the weights by a crazy amount.
-
-        if ( (cell->readouts->n > 1) ) {
-          psTrace("psModules.detrend",7,"Should be skipping scichip: %d\n",i);
-          psWarning ("Skipping Video Cell (%d) for ppImageDetrendFringe.c:getFringes", i);
-
-          if (i == 0) {
-            video_cell_zero = 1;
-          }
-          else {
-            pmFringeStats *prevFringe = fringes->data[i-1];
-            pmFringeStats *fringe     = pmFringeStatsAlloc(prevFringe->regions);
-            for (int j = 0; j < fringe->regions->nRequested; j++) {
-              fringe->f->data.F32[j] = prevFringe->f->data.F32[j];
-              fringe->df->data.F32[j] = prevFringe->df->data.F32[j] / 1e6;
-            }
-            fringes->data[i] = fringe;
-          }
-
-          continue;
-        }
-
-        fringes->data[i] = psMemIncrRefCounter(psMetadataLookupPtr(NULL, cell->analysis, source));
-    }
-
-    if (video_cell_zero == 1) {
-      pmFringeStats *prevFringe = fringes->data[1];
-      pmFringeStats *fringe     = pmFringeStatsAlloc(prevFringe->regions);
-      for (int j = 0; j < fringe->regions->nRequested; j++) {
-        fringe->f->data.F32[j] = NAN;
-        fringe->df->data.F32[j] = 1.0;
-      }
-      fringes->data[0] = fringe;
-    }
-
-    return fringes;
-}
-
-
-// Solve the fringe system: we have science fringe measurements for each cell, and an array of reference
-// fringe measurements for each cell.  Need to concatenate these together first, and then solve.
-bool ppImageDetrendFringeSolve(pmChip *scienceChip, const pmChip *refChip, const bool isResidual, const ppImageOptions *options)
-{
-    PS_ASSERT_PTR_NON_NULL(scienceChip, NULL);
-    PS_ASSERT_PTR_NON_NULL(refChip, NULL);
-    PS_ASSERT_PTR_NON_NULL(options, NULL);
-
-    psArray *science = NULL;
-    if (isResidual) {
-        science = getFringes(scienceChip,  "FRINGE.RESIDUALS"); // Fringe residuals on science chip
-    } else {
-        science = getFringes(scienceChip, "FRINGE.MEASUREMENTS"); // Fringe measurements on science chip
-    }
-
-    pmFringeStats *scienceCat = pmFringeStatsConcatenate(science, NULL, NULL); // Science fringes
-    psFree(science);
-
-    // Need to transform the array of cells each with an array of fringes --> array of fringes for the chip as
-    // a whole
-    psArray *references = getFringes(refChip, "FRINGE.MEASUREMENTS"); // Fringe measurements on reference chip
-    int numRefs = ((psArray*)references->data[0])->n; // Number of reference fringes
-    psArray *referencesCat = psArrayAlloc(numRefs);   // Reference fringes
-    for (int i = 0; i < numRefs; i++) {               // Iterate over fringes
-        psArray *refs = psArrayAlloc(references->n);  // Array of fringes for each cell
-        for (int j = 0; j < references->n; j++) {     // Iterate over cells
-            psArray *ref = references->data[j];       // Array of references for this cell
-
-            refs->data[j] = psMemIncrRefCounter(ref->data[i]);
-        }
-        referencesCat->data[i] = pmFringeStatsConcatenate(refs, NULL, NULL);
-        psFree(refs);
-    }
-    psFree(references);
-
-    // Now we can solve
-    psTrace("ppImage", 3, "Solving fringe system...\n");
-    pmFringeScale *solution = pmFringeScaleMeasure(scienceCat, referencesCat, options->fringeRej,
-                                                   options->fringeIter, options->fringeKeep);
-
-    if (isResidual) {
-        psMetadataAdd(scienceChip->analysis, PS_LIST_TAIL, "FRINGE.RESIDUAL.SOLUTION", PS_DATA_UNKNOWN, "Fringe solution", solution);
-    } else {
-        psMetadataAdd(scienceChip->analysis, PS_LIST_TAIL, "FRINGE.SOLUTION", PS_DATA_UNKNOWN, "Fringe solution", solution);
-    }
-
-# if (0)
-    // write the fringe amplitude or residual amplitude to the header
-    // XXX this is measured per cell, but we only have headers per chip
-    pmHDU *hdu = pmHDUFromCell(science);// HDU  of interest
-    for (int i = 0; i < solution->nFringeFrames; i++) {
-        // write metadata header value
-        psString keyword = NULL;
-        if (isResidual) {
-            psStringAppend (&keyword, "FRES_%02dV", i);
-        } else {
-            psStringAppend (&keyword, "FRNG_%02dV", i);
-        }
-        psMetadataAddF32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, "Fringe Amplitude", solution->coeff->data.F32[i + 1]);
-        psFree (keyword);
-
-        keyword = NULL;
-        if (isResidual) {
-            psStringAppend (&keyword, "FRES_%02dE", i);
-        } else {
-            psStringAppend (&keyword, "FRNG_%02dE", i);
-        }
-        psMetadataAddF32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, "Fringe Amplitude error", solution->coeffErr->data.F32[i + 1]);
-        psFree (keyword);
-    }
-# endif
-
-    psFree(solution);
-    psFree(scienceCat);
-    psFree(referencesCat);
-
-    return true;
-}
-
-
-bool ppImageDetrendFringeGenerate(pmCell *science, pmCell *fringes, const ppImageOptions *options)
-{
-    PS_ASSERT_PTR_NON_NULL(science, false);
-    PS_ASSERT_PTR_NON_NULL(fringes, false);
-
-    pmFringeScale *solution = psMetadataLookupPtr(NULL, science->parent->analysis, "FRINGE.SOLUTION");
-    if (!solution) {
-        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find fringe solution.\n");
-        return false;
-    }
-    assert(fringes->readouts->n == solution->nFringeFrames);
-
-    psImageMaskType maskVal = options->flatMask;
-
-    bool mdok;                          // Status of MD lookup
-    float expTime = psMetadataLookupF32(&mdok, science->concepts, "CELL.EXPOSURE"); // Exp. time
-    if (!mdok || !isfinite(expTime)) {
-        psError(PS_ERR_UNKNOWN, true, "CELL.EXPOSURE is not set --- can't renormalise fringes\n");
-        return false;
-    }
-    if (expTime == 0) {
-        psWarning("Exposure time is zero --- are you sure you want fringe subtraction?\n");
-        expTime = 1.0;
-    }
-
-    pmHDU *hdu = pmHDUFromCell(science);// HDU  of interest
-
-    // Construct the fringe image from the scale
-    psTrace("ppImage", 3, "Generating fringe correction...\n");
-    psImage *sumFringe = NULL; // Sum of the fringes
-    for (int i = 0; i < solution->nFringeFrames; i++) {
-        pmReadout *fringeRO = fringes->readouts->data[i]; // Fringe readout
-        psImage *fringe = fringeRO->image; // Fringe image
-        psTrace("ppImage", 5, "Scale for fringe component %d is %f\n",
-                i, solution->coeff->data.F32[i + 1]);
-        psBinaryOp(fringe, fringe, "*", psScalarAlloc(solution->coeff->data.F32[i + 1], PS_TYPE_F32));
-        if (!sumFringe) {
-            sumFringe = psImageCopy(NULL, fringe, PS_TYPE_F32);
-        } else {
-            psBinaryOp(sumFringe, sumFringe, "+", fringe);
-        }
-
-        psVector *md5 = psImageMD5(fringe); // md5 hash
-        psString md5string = psMD5toString(md5); // String
-        psFree(md5);
-        psStringPrepend(&md5string, "Fringe image %d (scale %.3f) MD5: ",
-                        i, solution->coeff->data.F32[i + 1]);
-        psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK,
-                         md5string, "");
-        psFree(md5string);
-
-# if (0)
-        // write metadata header value
-        // XXX this is measured per cell, but we only have headers per chip
-        psString keyword = NULL;
-        psStringAppend (&keyword, "FRNG_%02dV", i);
-        psMetadataAddF32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, "Fringe Amplitude", solution->coeff->data.F32[i + 1]);
-        psFree (keyword);
-
-        keyword = NULL;
-        psStringAppend (&keyword, "FRNG_%02dE", i);
-        psMetadataAddF32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, "Fringe Amplitude error", solution->coeffErr->data.F32[i + 1]);
-        psFree (keyword);
-# endif
-
-    }
-    if (expTime != 1.0) {
-        psBinaryOp(sumFringe, sumFringe, "*", psScalarAlloc(expTime, PS_TYPE_F32));
-    }
-
-    // Apply the correction to all readouts
-    psArray *readouts = science->readouts; // Array of science readouts
-    for (int i = 0; i < readouts->n; i++) {
-        pmReadout *readout = readouts->data[i]; // Readout of interest
-        if (!readout || !readout->data_exists) {
-            continue;
-        }
-
-        // subtract fringe and update mask if fringe value is NAN
-        for (int iy = 0; iy < readout->image->numRows; iy++) {
-            for (int ix = 0; ix < readout->image->numCols; ix++) {
-                readout->image->data.F32[iy][ix] -= sumFringe->data.F32[iy][ix];
-                if (!isfinite(sumFringe->data.F32[iy][ix]) && readout->mask) {
-                    readout->mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= maskVal;
-                }
-            }
-        }
-
-        // XXX: Make generic, so subregions may be subtracted as well
-        // if (!psBinaryOp(readout->image, readout->image, "-", sumFringe)) {
-        //     psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to subtract fringe.\n");
-        //     return false;
-        // }
-
-        // measure residual fringe amplitude. results go to FRINGE.RESIDUALS
-        ppImageDetrendFringeMeasure (readout, fringes, true, options);
-    }
-    psFree(sumFringe);
-
-    psTime *time = psTimeGetNow(PS_TIME_TAI); // The time now, used for reporting
-    psString timeString = psTimeToISO(time); // String with time
-    psFree(time);
-    psStringPrepend(&timeString, "Fringe correction completed at ");
-    psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK,
-                     timeString, "");
-    psFree(timeString);
-
-    return true;
-}
-
-bool ppImageDetrendFringeApply (pmConfig *config, pmChip *chip, const pmFPAview *inputView, const ppImageOptions *options) {
-
-    pmCell *cell = NULL;
-
-    assert (options->doFringe); // do not call if not needed
-    assert (inputView->chip != -1);
-    assert (inputView->cell == -1);
-    assert (inputView->readout == -1);
-
-    pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
-    *view = *inputView;
-
-    // select the reference chip
-    pmChip *fringe = pmFPAfileThisChip(config->files, view, "PPIMAGE.FRINGE");
-    if (!fringe) {
-        psError(PS_ERR_UNKNOWN, false, "missing fringe reference data.\n");
-        psFree (view);
-        return false;
-    }
-
-    // Solve the fringe system
-    if (!ppImageDetrendFringeSolve(chip, fringe, false, options)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to solve the fringe system.\n");
-        psFree (view);
-        return false;
-    }
-
-    // Go back over the cells to apply the fringe correction
-    view->cell = view->readout = -1;
-    while ((cell = pmFPAviewNextCell(view, chip->parent, 1)) != NULL) {
-        if (!cell->process || !cell->file_exists) {
-            continue;
-        }
-
-        // Apply the fringe correction
-        psTrace("ppImage", 3, "Applying fringe correction...\n");
-        pmCell *fringeCell = pmFPAfileThisCell(config->files, view, "PPIMAGE.FRINGE");
-        if (!fringeCell) {
-            psError(PS_ERR_UNKNOWN, false, "missing fringe reference data.\n");
-            psFree (view);
-            return false;
-        }
-
-        // XXX for now, skip the video cells (cell->readouts->n > 1)
-        if (cell->readouts->n > 1) {
-          psWarning ("Skipping Video Cell for ppImageDetrendFringeApply");
-          continue;
-        }
-
-        if (!ppImageDetrendFringeGenerate(cell, fringeCell, options)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to apply fringe image.\n");
-            psFree (view);
-            return false;
-        }
-    }
-
-    // Solve the residual fringe system
-    if (!ppImageDetrendFringeSolve(chip, fringe, true, options)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to solve the residual fringe system.\n");
-        psFree (view);
-        return false;
-    }
-
-    psFree (view);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageDetrendNonLinear.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageDetrendNonLinear.c	(revision 29946)
+++ 	(revision )
@@ -1,149 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem) {
-
-    // These are the polynomial coefficients
-    psVector *coeff = dataItem->data.V; // The coefficient vector
-    if (coeff->type.type != PS_TYPE_F64) {
-        psVector *temp = psVectorCopy(NULL, coeff, PS_TYPE_F64); // F64 version
-        psFree (coeff);
-        coeff = temp;
-    }
-    psPolynomial1D *correction = psPolynomial1DAlloc(coeff->n - 1, PS_POLYNOMIAL_ORD);
-    psFree(correction->coeff);
-    correction->coeff = psMemIncrRefCounter(coeff->data.F64);
-    pmNonLinearityPolynomial(input, correction);
-    psFree(coeff);
-    psFree(correction);
-    return true;
-}
-
-bool ppImageDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem) {
-
-    // This is a filename: lookup table
-    char *name = dataItem->data.V;       // Filename
-    psLookupTable *table = psLookupTableAlloc(name, "%f %f", 0);
-    if (psLookupTableRead(table) <= 0) {
-        psErrorStackPrint(stderr, "Unable to read non-linearity correction file "
-                          "%s --- ignored\n", name);
-        return false;
-    }
-#ifdef PRODUCTION
-    pmNonLinearityLookup(input, table);
-#else
-    psVector *influx = table->values->data[0];
-    psVector *outflux = table->values->data[1];
-    pmNonLinearityLookup(input, influx, outflux);
-#endif
-    psFree(table);
-    return true;
-}
-
-
-bool ppImageDetrendNonLinear(pmReadout *input, pmFPAview *detview, pmConfig  *config) {
-    bool status;
-
-    pmFPAfile *linearity_file = psMetadataLookupPtr(&status,config->files,"PPIMAGE.LINEARITY");
-    psFits *linearity_fits = linearity_file->fits;
-
-    char *extname = psMetadataLookupStr(&status,input->parent->concepts,"CELL.NAME");
-    if (!extname) {
-	psError(PS_ERR_IO, false, "missing CELL.NAME in concepts");
-	return(false);
-    }
-
-    if (!psFitsMoveExtName(linearity_fits,extname)) {
-	psError(PS_ERR_IO, false, "Unable to move to non-linearity table %s", extname);
-	return(false);
-    }
-  
-    psArray *table = psFitsReadTable(linearity_fits);
-    if (!table) {
-	psError(PS_ERR_IO, false, "Unable to read non-linearity table.\n");
-	return(false);
-    }
-
-    // It might be better to pack lookup table here...
-    // Why? I only use that lookup table once for the single cell it matches. 
-  
-    if (!pmNonLinearityApply(input,table)) {
-	psError(PS_ERR_UNKNOWN, false, "Unable to apply non-linearity corrections.\n");
-	psFree (table);
-	return(false);
-    }	    
-    psFree (table);
-
-    return true;
-}
-
-bool ppImageDetrendNonLinear_Original(pmReadout *input, ppImageOptions *options) {
-
-    psMetadataItem *concept;
-    pmCell *cell = input->parent;
-
-    switch (options->nonLinearType) {
-      case PS_DATA_VECTOR:
-        ppImageDetrendNonLinearPolynomial (input, options->nonLinearData);
-        return true;
-
-      case PS_DATA_STRING:
-        ppImageDetrendNonLinearLookup (input, options->nonLinearData);
-        return true;
-
-      case PS_DATA_METADATA:
-        // Go looking for the value in the hierarchy
-        concept = psMetadataLookup(cell->concepts, options->nonLinearSource);
-        if (! concept) {
-            pmChip *chip = cell->parent;// Parent chip
-            concept = psMetadataLookup(chip->concepts, options->nonLinearSource);
-            if (! concept) {
-                pmFPA *fpa = chip->parent; // Parent FPA
-                concept = psMetadataLookup(fpa->concepts, options->nonLinearSource);
-                if (! concept) {
-                    psLogMsg("phase2", PS_LOG_WARN, "Unable to find value of concept %s "
-                             "for non-linearity correction --- ignored.\n", (char *)options->nonLinearSource);
-                    return false;
-                }
-            }
-        }
-
-        if (concept->type != PS_DATA_STRING) {
-            psLogMsg("phase2", PS_LOG_WARN, "Type for concept %p isn't STRING, as"
-                     " expected for non-linearity correction --- ignored.\n",
-                     concept);
-            return false;
-        }
-
-        // Get the value of the concept
-        psString conceptValue = concept->data.V;
-        psMetadata *folder = (psMetadata *)options->nonLinearData->data.V;
-        psMetadataItem *optionItem = psMetadataLookup(folder, conceptValue);
-        if (!optionItem) {
-            psLogMsg("phase2", PS_LOG_WARN, "Unable to find %s in NONLIN.DATA"
-                     " --- ignored.\n", conceptValue);
-            return false;
-        }
-
-        switch (optionItem->type) {
-          case PS_DATA_VECTOR:
-            ppImageDetrendNonLinearPolynomial (input, optionItem);
-            return true;
-          case PS_DATA_STRING:
-            ppImageDetrendNonLinearLookup (input, optionItem);
-            return true;
-          default:
-            psLogMsg("phase2", PS_LOG_WARN, "Non-linearity correction "
-                     "desired but unable to interpret NONLIN.DATA for %s"
-                     " --- ignored\n", conceptValue);
-            return false;
-        }
-      default:
-        psAbort("Invalid options->nonLinearType");
-    }
-    return true;
-}
-
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageDetrendPattern.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageDetrendPattern.c	(revision 29946)
+++ 	(revision )
@@ -1,160 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-#define ESCAPE(STATUS,...) {                    \
-        psError(PS_ERR_UNKNOWN, STATUS, __VA_ARGS__);   \
-        psFree(view);                                   \
-        return false;                                   \
-    }
-
-static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue);
-
-bool ppImageDetrendPatternApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView,
-                                const ppImageOptions *options)
-{
-    pmCell *cell = NULL;
-
-    assert(options->doPatternRow || options->doPatternCell); // do not call if not needed
-    assert(inputView->chip != -1);
-    assert(inputView->cell == -1);
-    assert(inputView->readout == -1);
-
-    if (options->doPatternRow) {
-        bool status;
-        pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.INPUT");
-        pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
-        *view = *inputView;
-        while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
-            if (!cell->process || !cell->file_exists) {
-                continue;
-            }
-            if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-              ESCAPE(false, "load failure for Cell");
-            }
-
-            if (!cell->data_exists) {
-                continue;
-            }
-
-            if (cell->readouts->n > 1) {
-                psWarning ("Skipping Video Cell for ppImageDetrendPatternApply");
-                continue;
-            }
-
-            bool doPattern = false;
-            if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET")) {
-                ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
-            }
-            if (!doPattern) continue;
-
-            const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
-            const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
-            psLogMsg("ppImage", PS_LOG_INFO, "Performing row pattern correction for %s, %s\n",
-                     chipName, cellName);
-
-            // process each of the readouts
-            pmReadout *readout;         // Readout from cell
-            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
-                if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-                    ESCAPE(false, "load failure for Readout");
-                }
-                if (!readout->data_exists) {
-                    continue;
-                }
-
-                // Perform pattern correction
-                if (!pmPatternRow(readout, options->patternRowOrder, options->patternRowIter,
-                                  options->patternRowRej, options->patternRowThresh, options->patternRowMean,
-                                  options->patternRowStdev, options->maskValue, options->darkMask)) {
-                    psFree(view);
-                    return(false);
-                }
-            }
-        }
-        psFree(view);
-    }
-
-    if (options->doPatternCell) {
-        int numCells = chip->cells->n;       // Number of cells
-        psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell?
-        pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
-        *view = *inputView;
-        for (int i = 0; i < chip->cells->n; i++) {
-            view->cell = i;
-
-            pmCell *cell = chip->cells->data[i]; // Cell of interest
-            if (cell->readouts->n > 1) {
-                psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction on video cell.");
-                continue;
-            }
-
-            bool doPattern = false;
-            if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET")) {
-                ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
-            }
-            if (doPattern) {
-                tweak->data.U8[i] = 0xFF;
-            }
-        }
-
-        // Tweak the cells
-        if (!pmPatternCell(chip, tweak, options->patternCellBG, options->patternCellMean,
-                           options->maskValue, options->darkMask)) {
-            psFree(tweak);
-            psFree(view);
-            return false;
-        }
-        psFree(tweak);
-        psFree(view);
-    }
-
-    return(true);
-}
-
-static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue) {
-
-    *doit = false;
-
-    psMetadataItem *doPattern = pmConfigRecipeValueByView(config, recipeName, recipeValue, chip->parent, view);
-    if (!doPattern) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to determine whether row pattern matching should be applied.");
-        return false;
-    }
-    if (doPattern->type == PS_DATA_BOOL) {
-        *doit = doPattern->data.B;
-        return true;
-    }
-    if (doPattern->type == PS_DATA_STRING) {
-        // expect a string of the form "000110001001" with at least view->cell entries
-        char *string = doPattern->data.str;
-        if (strlen(string) < view->cell) {
-            psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string (too few elements %d)", (int) strlen(string));
-            return false;
-        }
-        switch (string[view->cell]) {
-          case '0':
-          case 'f':
-          case 'F':
-          case 'n':
-          case 'N':
-            *doit = false;
-            return true;
-          case '1':
-          case 't':
-          case 'T':
-          case 'y':
-          case 'Y':
-            *doit = true;
-            return true;
-          default:
-            psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string %s (unknown value %c))", string, string[view->cell]);
-            return false;
-        }
-        psAbort("imposible to reach here");
-    }
-    psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET : invalid data type");
-    return false;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageDetrendReadout.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageDetrendReadout.c	(revision 29946)
+++ 	(revision )
@@ -1,248 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageDetrendReadout(pmConfig *config, ppImageOptions *options, pmFPAview *view)
-{
-    // construct a view for the detrend images (which have only one readout)
-    pmFPAview *detview = pmFPAviewAlloc(0);
-    *detview = *view;
-    detview->readout = 0;
-
-    // find the currently selected readout
-    pmReadout *input = pmFPAfileThisReadout(config->files, view, "PPIMAGE.INPUT");
-
-    // Check that the gain is set (this is used by both pmReadoutGenerateMask and pmReadoutGenerateVariance)
-    { 
-      float gain = psMetadataLookupF32(NULL, input->parent->concepts, "CELL.GAIN"); // Gain for cell
-      if (!isfinite(gain)) {
-	psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, RECIPE_NAME); // Recipe
-	psAssert(recipe, "Should be there!");
-	bool override = psMetadataLookupBool(NULL, recipe, "GAIN.OVERRIDE"); // Override the bad gain?
-	if (override) {
-	  psWarning("CELL.GAIN is not set for readout (%d,%d,%d) --- setting to unity.", view->chip, view->cell, view->readout);
-	  psMetadataItem *item = psMetadataLookup(input->parent->concepts, "CELL.GAIN"); // Gain item
-	  psAssert(item, "Should be there!");
-	  item->data.F32 = 1.0;
-
-	  // for unity gain, there is no modification for the readnoise, note that it has (effectively) been updated
-	  psMetadataRemoveKey(input->parent->concepts, "CELL.READNOISE.UPDATE");
-	} else {
-	  psWarning("CELL.GAIN is NAN for readout (%d,%d,%d), image will be masked.", view->chip, view->cell, view->readout);
-	}
-      }
-    }
-
-    // Masking on the basis of pixel value needs to be done before anything else, so the values are pristine.
-    if (options->doMaskBuild) {
-        psImageMaskType satMask = options->doMaskSat ? options->satMask : 0;
-        psImageMaskType lowMask = options->doMaskLow ? options->lowMask : 0;
-        pmReadoutGenerateMask(input, satMask, lowMask);
-    }
-    // apply the externally supplied mask to the input->mask pixels
-    if (options->doMask) {
-        pmReadout *mask = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.MASK");
-        pmMaskBadPixels(input, mask, options->maskValue);
-    }
-    if (options->doMaskBurntool) {
-      ppImageBurntoolMask(config,options,view,input);
-    }
-
-    // Subtract the overscan
-    if (options->doOverscan) {
-      if (!pmOverscanSubtract (input, options->overscan)) {
-	psError(PS_ERR_UNKNOWN, false, "Unable to subtract overscan.");
-	psFree(detview);
-	return false;
-      }
-    }
-
-    // Non-linearity correction
-    if (options->doNonLin) {
-      //      linearity = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.LINEARITY");
-      if (!ppImageDetrendNonLinear(input,detview,config)) {
-	psError(PS_ERR_UNKNOWN, false, "Unable to correct NonLinearity");
-	psFree(detview);
-	return(false);
-      }
-      /*       ppImageDetrendNonLinear(detrend->input, input, options); */
-    }
-
-    // set up the dark and bias
-    pmCell *dark = NULL;                // Multi-dark
-    pmReadout *oldDark = NULL;          // Old-fashioned dark
-    pmReadout  *bias = NULL;
-    if (options->doBias) {
-        bias = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.BIAS");
-    }
-    if (options->doDark) {
-        bool mdok;                      // Status of MD lookup
-        psMetadata *recipe = psMetadataLookupPtr (&mdok, config->recipes, RECIPE_NAME);
-        assert(mdok && recipe);
-        if (psMetadataLookupBool(&mdok, recipe, "OLDDARK")) {
-            oldDark = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.DARK");
-        } else {
-            dark = pmFPAfileThisCell(config->files, detview, "PPIMAGE.DARK");
-        }
-    }
-
-    // Bias and temperature-independent-dark subtraction are merged.
-    if (options->doBias) {
-        if (!pmBiasSubtract(input, bias, oldDark, view)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to subtract bias.");
-            psFree(detview);
-            return false;
-        }
-    }
-    
-    // Weight on the basis of pixel value needs to be done after the overscan has been subtracted
-    if (options->doVarianceBuild) {
-        // create the target mask and variance images
-        psImage *noiseImage = NULL;
-        if (options->doNoiseMap) {
-            // XXX convert the noiseMap image to a binned image
-            pmReadout *noiseMap = NULL;
-            noiseMap = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.NOISEMAP");
-            noiseImage = psImageCopy (NULL, input->image, PS_TYPE_F32);
-            psImageInit (noiseImage, 0.0);
-
-            // XXX this works, but is not really quite right: the model shoud include the
-            // offset information, we are not really getting exactly the right mapping from the
-            // original file.
-            psImageBinning *binning = psImageBinningAlloc();
-            binning->nXruff = noiseMap->image->numCols;
-            binning->nYruff = noiseMap->image->numRows;
-            binning->nXfine = input->image->numCols;
-            binning->nYfine = input->image->numRows;
-            psImageBinningSetScale(binning, PS_IMAGE_BINNING_LEFT);
-
-            psImageUnbin (noiseImage, noiseMap->image, binning);
-            psFree (binning);
-        }
-
-        pmReadoutGenerateVariance(input, noiseImage, true);
-        psFree (noiseImage);
-    }
-
-    if (options->doDark && dark) {
-        if (!pmDarkApply(input, dark, options->darkMask)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to subtract dark.");
-            psFree(detview);
-            return false;
-        }
-    }
-
-    if (options->doRemnance) {
-        if (!pmRemnance(input, options->maskValue, options->lowMask,
-                        options->remnanceSize, options->remnanceThresh)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to mask remnance.");
-            psFree(detview);
-            return false;
-        }
-    }
-
-    // Shutter correction
-    if (options->doShutter) {
-        pmReadout *shutter = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.SHUTTER");
-        if (!pmShutterCorrectionApply(input, shutter, pmConfigMaskGet("FLAT", config))) {
-            psFree(detview);
-            return false;
-        }
-    }
-
-    // Flat-field correction (no options used?)
-    if (options->doFlat) {
-        pmReadout *flat = pmFPAfileThisReadout(config->files, detview, "PPIMAGE.FLAT");
-        if (!pmFlatField(input, flat, options->flatMask)) {
-            psFree(detview);
-            return false;
-        }
-    }
-
-/*     // Pattern noise correction */
-/*     if (options->doPattern) { */
-/*         if (!pmPatternRow(input, options->patternOrder, options->patternIter, options->patternRej, */
-/*                           options->patternThresh, options->patternMean, options->patternStdev, */
-/*                           options->maskValue, options->darkMask)) { */
-/*             psFree(detview); */
-/*             return false; */
-/*         } */
-/*     } */
-
-    // Normalization by a single (known) constant
-    bool mdok;                          // Status of MD lookup
-    float norm = psMetadataLookupF32(&mdok, config->arguments, "NORMALIZATION");
-    if (mdok && isfinite(norm) && norm != 1.0) {
-        pmHDU *hdu = pmHDUFromReadout(input); // HDU of interest
-        psString comment = NULL;        // Comment to add
-        psStringAppend(&comment, "Normalization: %f", norm);
-        psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, "");
-        psFree(comment);
-
-        psBinaryOp(input->image, input->image, "*", psScalarAlloc(norm, PS_TYPE_F32));
-    }
-
-# if (1)
-    // Normalization by per-class values
-    psMetadata *normlist = psMetadataLookupMetadata(&mdok, config->arguments, "NORMALIZATION.TABLE");
-    if (normlist) {
-        pmFPAfile *inputFile = psMetadataLookupPtr(&mdok, config->files, "PPIMAGE.INPUT");
-
-        // get the menu of class IDs
-        psMetadata *menu = psMetadataLookupMetadata(&mdok, inputFile->camera, "CLASSID");
-        if (!menu) {
-            psError(PS_ERR_IO, false, "Unable to find CLASSID metadata in camera configuration");
-            psFree(detview);
-            return false;
-        }
-        // get the rule for class_id for the desired class
-        const char *rule = psMetadataLookupStr(&mdok, menu, options->normClass);
-        if (!rule) {
-            psError(PS_ERR_IO, false, "Unable to find NORM.CLASS value %s in CLASSID in camera configuration", options->normClass);
-            psFree(detview);
-            return false;
-        }
-        // get the class_id from the rule
-        char *classID = pmFPAfileNameFromRule(rule, inputFile, view);
-        if (!classID) {
-            psError(PS_ERR_IO, false, "error converting CLASSID rule %s to name\n", rule);
-            psFree(detview);
-            return false;
-        }
-
-        // get normalization from the class_id
-        float norm = psMetadataLookupF32 (&mdok, normlist, classID);
-        if (!mdok) {
-            psError(PS_ERR_IO, false, "failed to find class ID %s in normalization table\n", classID);
-            psFree(detview);
-            return false;
-        }
-
-        pmHDU *hdu = pmHDUFromReadout(input); // HDU of interest
-        psString comment = NULL;        // Comment to add
-        psStringAppend(&comment, "Normalization: %f", norm);
-        psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, "");
-        psFree(comment);
-
-        // apply the normalization
-        psBinaryOp(input->image, input->image, "*", psScalarAlloc(norm, PS_TYPE_F32));
-
-        psFree (classID);
-    }
-# endif
-
-    if (options->doFringe) {
-        pmCell *fringe = pmFPAfileThisCell(config->files, detview, "PPIMAGE.FRINGE");
-        if (!ppImageDetrendFringeMeasure(input, fringe, false, options)) {
-            psFree(detview);
-            return false;
-        }
-    }
-
-    ppImageMemoryDump("detrend");
-
-    psFree(detview);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageDetrendRecord.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageDetrendRecord.c	(revision 29946)
+++ 	(revision )
@@ -1,79 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-static void detrendRecord(
-    bool doThis,                        // Are we supposed to do this?
-    psMetadata *target,                 // Target metadata
-    const pmConfig *config,             // Configuration
-    const pmFPAview *view,              // View to cell
-    const char *filename,               // Name of file
-    const char *name,                   // Name in header
-    const char *desc                    // Description
-    )
-{
-    psAssert(config, "Need configuration");
-    psAssert(view, "Need view to cell");
-    psAssert(name, "Need file name");
-
-    if (!doThis) {
-        return;
-    }
-
-    pmFPAfile *file = psMetadataLookupPtr(NULL, config->files, filename); // File of interest
-    psAssert(file, "Should be there");
-
-    if (target) {
-        psMetadataAddStr(target, PS_LIST_TAIL, name, 0, desc, file->filename);
-    }
-
-    pmCell *input = pmFPAfileThisCell(config->files, view, "PPIMAGE.INPUT"); // File we're processing
-    psAssert(input, "Should be there");
-    pmHDU *hdu = pmHDUGetHighest(input->parent->parent, input->parent, input);  // HDU for cell
-
-    // Strip off path and Nebulous bits
-    char *base = file->filename;        // Base name of file
-    for (char *new = base; (new = strpbrk(base, "/:")); base = new + 1); // No action
-
-    // We don't want multiple listings in the header saying the same thing, so make sure we haven't put the
-    // same entry there.  Usually (if the detrend and the image have the same file level) there'll only end up
-    // being one entry.
-    psString regexp = NULL;             // Regular expression
-    psStringAppend(&regexp, "^%s$", name);
-    psMetadataIterator *iter = psMetadataIteratorAlloc(hdu->header, PS_LIST_HEAD, regexp); // Iterator for hdr
-    psFree(regexp);
-    psMetadataItem *item;               // Item from iteration
-    bool found = false;
-    while (!found && (item = psMetadataGetAndIncrement(iter))) {
-        if (item->type == PS_DATA_STRING && strcmp(item->data.str, base) == 0) {
-            found = true;
-        }
-    }
-    psFree(iter);
-    if (!found) {
-        psMetadataAddStr(hdu->header, PS_LIST_TAIL, name, PS_META_DUPLICATE_OK, desc, base);
-    }
-
-    return;
-}
-
-
-bool ppImageDetrendRecord(pmCell *cell, const pmConfig *config, const ppImageOptions *options,
-                          const pmFPAview *view)
-{
-    psMetadata *detrend = psMetadataAlloc(); // Detrend information
-    psMetadataAddMetadata(cell->analysis, PS_LIST_TAIL, "DETREND", 0, "Detrend information", detrend);
-
-    detrendRecord(options->doMask,     detrend, config, view, "PPIMAGE.MASK", 	  "DETREND.MASK",     "Mask filename");
-    detrendRecord(options->doNoiseMap, detrend, config, view, "PPIMAGE.NOISEMAP", "DETREND.NOISEMAP", "Noise Map filename");
-    detrendRecord(options->doBias,     detrend, config, view, "PPIMAGE.BIAS", 	  "DETREND.BIAS",     "Bias filename");
-    detrendRecord(options->doDark,     detrend, config, view, "PPIMAGE.DARK", 	  "DETREND.DARK",     "Dark filename");
-    detrendRecord(options->doShutter,  detrend, config, view, "PPIMAGE.SHUTTER",  "DETREND.SHUTTER",  "Shutter correction filename");
-    detrendRecord(options->doFlat,     detrend, config, view, "PPIMAGE.FLAT",     "DETREND.FLAT",     "Flat filename");
-    detrendRecord(options->doFringe,   detrend, config, view, "PPIMAGE.FRINGE",   "DETREND.FRINGE",   "Fringe filename");
-
-    psFree (detrend);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageErrorCodes.c.in
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageErrorCodes.c.in	(revision 29946)
+++ 	(revision )
@@ -1,26 +1,0 @@
-/*
- * The line
-    { PPIMAGE_ERR_$X{ErrorCode}, "$X{ErrorDescription}"},
- * (without the Xs)
- * will be replaced by values from errorCodes.dat
- */
-#include "pslib.h"
-#include "ppImageErrorCodes.h"
-
-void ppImageErrorRegister(void)
-{
-    static psErrorDescription errors[] = {
-       { PPIMAGE_ERR_BASE, "First value we use; lower values belong to psLib" },
-       { PPIMAGE_ERR_${ErrorCode}, "${ErrorDescription}"},
-    };
-    static int nerror = PPIMAGE_ERR_NERROR - PPIMAGE_ERR_BASE; // number of values in enum
-
-    for (int i = 0; i < nerror; i++) {
-       psErrorDescription *tmp = psAlloc(sizeof(psErrorDescription));
-       p_psMemSetPersistent(tmp, true);
-       *tmp = errors[i];
-       psErrorRegister(tmp, 1);
-       psFree(tmp);			/* it's on the internal list */
-    }
-    nerror = 0;			                // don't register more than once
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageErrorCodes.dat
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageErrorCodes.dat	(revision 29946)
+++ 	(revision )
@@ -1,10 +1,0 @@
-#
-# This file is used to generate ppImageErrorClasses.h
-
-BASE = 5000		First value we use; lower values belong to psLib
-# these errors correspond to standard exit conditions
-ARGUMENTS               Incorrect arguments
-SYS                     System error
-CONFIG                  Problem in configure files
-PROG                    Programming error
-DATA                    invalid data
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageErrorCodes.h.in
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageErrorCodes.h.in	(revision 29946)
+++ 	(revision )
@@ -1,18 +1,0 @@
-#if !defined(PPIMAGE_ERROR_CODES_H)
-#define PPIMAGE_ERROR_CODES_H
-/*
- * The line
- *  PPIMAGE_ERR_$X{ErrorCode},
- * (without the X)
- *
- * will be replaced by values from errorCodes.dat
- */
-typedef enum {
-    PPIMAGE_ERR_BASE = 5000,
-    PPIMAGE_ERR_${ErrorCode},
-    PPIMAGE_ERR_NERROR
-} ppImageErrorCode;
-
-void ppImageErrorRegister(void);
-
-#endif
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageFileCheck.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageFileCheck.c	(revision 29946)
+++ 	(revision )
@@ -1,60 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-void ppImageFileCheck (pmConfig *config) {
-
-    // add the output names to the output-type files
-    psMetadataItem *item = NULL;
-    psMetadataIterator *iter = psMetadataIteratorAlloc (config->files, PS_LIST_HEAD, NULL);
-    while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
-        pmFPAfile *file = item->data.V;
-        pmFPA *fpa = file->fpa;
-        fprintf (stderr, "file %s\n", file->name);
-        if (!fpa) {
-            fprintf (stderr, "  has no FPA\n");
-            continue;
-        }
-        if (fpa->hdu) {
-            if (fpa->hdu->images) fprintf (stderr, "  (%d,%d) images\n", -1, -1);
-            if (fpa->hdu->variances) fprintf (stderr, "  (%d,%d) variances\n", -1, -1);
-            if (fpa->hdu->masks) fprintf (stderr, "  (%d,%d) masks\n", -1, -1);
-            if (fpa->hdu->header) fprintf (stderr, "  (%d,%d) header\n", -1, -1);
-        } else {
-            // fprintf (stderr, "  has no fpa data (%d,%d)\n", -1, -1);
-        }
-        for (int i = 0; i < fpa->chips->n; i++) {
-            pmChip *chip = fpa->chips->data[i];
-            if (chip->hdu) {
-                if (chip->hdu->images) fprintf (stderr, "  (%d,%d) images\n", i, -1);
-                if (chip->hdu->variances) fprintf (stderr, "  (%d,%d) variances\n", i, -1);
-                if (chip->hdu->masks) fprintf (stderr, "  (%d,%d) masks\n", i, -1);
-                if (chip->hdu->header) fprintf (stderr, "  (%d,%d) header\n", i, -1);
-            } else {
-                // fprintf (stderr, "  has no chip data (%d,%d)\n", i, -1);
-            }
-            for (int j = 0; j < chip->cells->n; j++) {
-                pmCell *cell = chip->cells->data[j];
-                if (cell->hdu) {
-                    if (cell->hdu->images) fprintf (stderr, "  (%d,%d) images\n", i, j);
-                    if (cell->hdu->variances) fprintf (stderr, "  (%d,%d) variances\n", i, j);
-                    if (cell->hdu->masks) fprintf (stderr, "  (%d,%d) masks\n", i, j);
-                    if (cell->hdu->header) fprintf (stderr, "  (%d,%d) header\n", i, j);
-                } else {
-                    // fprintf (stderr, "  has no cell data (%d,%d)\n", i, j);
-                }
-                for (int k = 0; k < cell->readouts->n; k++) {
-                    pmReadout *readout = cell->readouts->data[k];
-                    if (readout) {
-                        if (readout->image) fprintf (stderr, "  (%d,%d,%d) image\n", i, j, k);
-                        if (readout->variance) fprintf (stderr, "  (%d,%d,%d) variance\n", i, j, k);
-                        if (readout->mask) fprintf (stderr, "  (%d,%d,%d) masks\n", i, j, k);
-                    }
-                }
-            }
-        }
-    }
-    psFree (iter);
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageLoop.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageLoop.c	(revision 29946)
+++ 	(revision )
@@ -1,295 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-#define ESCAPE(MESSAGE) { \
-  psError(PS_ERR_UNKNOWN, false, MESSAGE); \
-  psFree(view); \
-  pmFPAfileFreeSetStrict(false); \
-  return false; \
-}
-
-bool ppImageLoop(pmConfig *config, ppImageOptions *options)
-{
-    psMetadata *stats = NULL;           // Statistics to output
-    float timeDetrend = 0;              // Amount of time spent in detrend
-    float timePhot = 0;                 // Amount of time spent in photometry
-
-    if (options->doStats) {
-        stats = psMetadataAlloc();
-        psMetadataAddS32(stats, PS_LIST_TAIL, "QUALITY", 0, "No problems", 0);
-    }
-
-    bool status;                        // Status of MD lookup
-    pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.INPUT");
-    if (!status) {
-        psErrorStackPrint(stderr, "Can't find input data!\n");
-        ppImageCleanup(config, options);
-        exit(PS_EXIT_PROG_ERROR);
-    }
-
-    pmConfigCamerasCull(config, NULL);
-    pmConfigRecipesCull(config, "PPIMAGE,PPSTATS,PSPHOT,MASKS,PSASTRO,JPEG");
-
-    pmFPAview *view = pmFPAviewAlloc(0);// View for level of interest
-    pmHDU *lastHDU = NULL;              // Last HDU that was updated
-
-    // files associated with the science image
-    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-        ESCAPE("load failure for FPA");
-    }
-
-    pmChip *chip;                       // Chip from FPA
-    while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) {
-        psLogMsg ("ppImageLoop", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
-        if (!chip->process || !chip->file_exists) {
-            continue;
-        }
-        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-            ESCAPE("load failure for Chip");
-        }
-
-        // crosstalk measurement needs to be done on the entire chip at once, and before
-        // signal levels are modified by the detrending.  If crosstalk measurement is
-        // requested, the read-level for the images is set to CHIP.
-        if (!ppImageMeasureCrosstalk(config, options, view)) {
-          ESCAPE("Unable to perform crosstalk correction");
-        }
-
-        // crosstalk correction needs to be done on the entire chip at once, and before
-        // signal levels are modified by the detrending.  If crosstalk correction is
-        // requested, the read-level for the images is set to CHIP.
-        if (!ppImageCorrectCrosstalk(config, options, view)) {
-          ESCAPE("Unable to perform crosstalk correction");
-        }
-
-        psTimerStart(TIMER_DETREND);
-        pmCell *cell;                   // Cell from chip
-        while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
-            psLogMsg ("ppImageLoop", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-            if (!cell->process || !cell->file_exists) {
-                continue;
-            }
-            if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-                ESCAPE("load failure for Cell");
-            }
-
-            // Put version information into the header
-            pmHDU *hdu = pmHDUGetHighest(input->fpa, chip, cell);
-            if (hdu && hdu != lastHDU) {
-                ppImageVersionHeader(hdu->header);
-                lastHDU = hdu;
-            }
-
-            // XXX for now, skip the video cells (cell->readouts->n > 1)
-            if (cell->readouts->n > 1) {
-              psWarning ("Skipping Video Cell for ppImageDetrendReadout");
-              continue;
-            }
-
-            // process each of the readouts
-            pmReadout *readout;         // Readout from cell
-            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
-                if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
-                    ESCAPE("load failure for Readout");
-                }
-                if (!readout->data_exists) {
-                    continue;
-                }
-
-                // flip the image to match the native detector orientation (to match bias, flat, etc)
-                if (!ppImageParityFlip(config, options, view, true)) {
-                    ESCAPE("Unable to detrend readout");
-                }
-
-                // XXX set the options->*Mask values here (after the mask images have been loaded
-                // and before any of the value are used)
-                if (!ppImageSetMaskBits(config, options)) {
-                    ESCAPE("Unable to set bit masks");
-                }
-
-                // perform the detrend analysis
-                if (!ppImageDetrendReadout(config, options, view)) {
-                    ESCAPE("Unable to detrend readout");
-                }
-
-                // free detrend images potentially in use: MASK, BIAS, DARK, SHUTTER, FLAT
-                if (!ppImageDetrendFree (config, view)) {
-                    ESCAPE("Unable to free detrend images");
-                }
-
-                // optionally measure CTE by examining the variance in a box
-                if (!ppImageCheckCTE (config, options, view)) {
-                    ESCAPE("Unable to measure CTE");
-                }
-            }
-
-            if (cell->data_exists) {
-                ppImageDetrendRecord(cell, config, options, view);
-            }
-
-            // process each of the readouts
-            // XXX reset the view to the first readout?
-            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
-                if (!readout->data_exists) {
-                    continue;
-                }
-                // flip the image to match the raw readout orientation
-                if (!ppImageParityFlip(config, options, view, false)) {
-                    ESCAPE("Unable to detrend readout");
-                }
-            }
-
-            // free detrend images potentially in use: MASK, BIAS, DARK, SHUTTER, FLAT
-            if (!ppImageDetrendFree (config, view)) {
-                ESCAPE("Unable to free detrend images");
-            }
-        }
-        // free detrend images potentially in use: MASK, BIAS, DARK, SHUTTER, FLAT
-        if (!ppImageDetrendFree (config, view)) {
-            ESCAPE("Unable to free detrend images");
-        }
-    
-        // Apply the fringe correction
-        if (options->doFringe) {
-            if (!ppImageDetrendFringeApply(config, chip, view, options)) {
-                ESCAPE("Unable to defringe");
-            }
-        }
-        // free detrend images potentially in use: MASK, BIAS, DARK, SHUTTER, FLAT
-        if (!ppImageFringeFree (config, view)) {
-            ESCAPE("Unable to free fringe images");
-        }
-
-        // Apply the pattern correction
-        if (options->doPatternRow || options->doPatternCell) {
-          if (!ppImageDetrendPatternApply(config,chip,view,options)) {
-            ESCAPE("Unable to apply pattern corrections");
-          }
-        }
-
-        // measure various pixel-based statistics for this image
-        if (!ppImagePixelStats(config, stats, options, view)) {
-            ESCAPE("Unable to measures pixel stats for image");
-        }
-
-        if (!ppImageMosaicChip(config, options, view, "PPIMAGE.CHIP", "PPIMAGE.OUTPUT")) {
-            ESCAPE("Unable to mosaic chip");
-        }
-        timeDetrend += psTimerClear(TIMER_DETREND);
-
-        // we perform photometry on the readouts of this chip in the output
-
-        psTimerStart(TIMER_PHOT);
-        if (options->doPhotom) {
-            if (!ppImagePhotom(stats, config, view)) {
-                ESCAPE("error running photometry.");
-            }
-        }
-        timePhot += psTimerClear(TIMER_PHOT);
-
-        // replace the masked pixels with the background level
-        if (options->doBG) {
-            if (!ppImageSubtractBackground(config, view, options)) {
-                ESCAPE("Unable to subtract background");
-            }
-        }
-
-	if (options->doMaskStats) {
-	  //if (!ppImageMaskStats(config, view, options)) {
-	  if (!ppImageMaskStats(config, view, stats)) {
-	    ESCAPE("Unable to do Mask stats");
-	  }
-	}
-	
-        // these may be used by ppImageSubtractBackground.
-        // if these are defined as internal files, drop them here
-        status = true;
-        status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL");
-        status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV");
-        status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND");
-        if (!status) {
-            psError(PSPHOT_ERR_PROG, false, "trouble dropping internal files");
-            psFree (view);
-            return false;
-        }
-
-        // binning (used for display) must take place after the background is replaced, if desired
-        if (!ppImageRebinChip(config, view, options, "PPIMAGE.BIN1")) {
-            ESCAPE("Unable to bin chip (level 1).");
-        }
-        if (!ppImageRebinChip(config, view, options, "PPIMAGE.BIN2")) {
-            ESCAPE("Unable to bin chip (level 2).");
-        }
-
-        // Close cells (XXX shouldn't pmFPAfileClose iterate down as needed?)
-        view->cell = -1;
-        while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
-            if (!cell->process || !cell->file_exists) {
-                continue;
-            }
-            if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-                ESCAPE("save failure for Cell");
-            }
-        }
-
-        // Close chip
-        if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-            ESCAPE("save failure for Chip");
-        }
-    }
-
-    // generate the full-scale FPA mosaic
-    if (!ppImageMosaicFPA(config, options, "PPIMAGE.OUTPUT.FPA1", "PPIMAGE.BIN1")) {
-        ESCAPE("failure in FPA Mosaic (level 1)");
-    }
-    if (!ppImageMosaicFPA(config, options, "PPIMAGE.OUTPUT.FPA2", "PPIMAGE.BIN2")) {
-        ESCAPE("failure in FPA Mosaic (level 2)");
-    }
-
-    // we perform astrometry on all chips after sources have been detected
-    // this also performs the psastro file IO
-    if (options->doAstromChip || options->doAstromMosaic) {
-        if (!ppImageAstrom(config, stats)) {
-            ESCAPE("error running astrometry.");
-        }
-    }
-
-    if (psTraceGetLevel("ppImage") >= 3) {
-        ppImageFileCheck(config);
-    }
-    
-    // Calculate summary statistics from FPA Metadata
-    if (!ppImageMetadataStats(config, stats, options)) {
-        ESCAPE("Unable to determine FPA-level metadata statistics.");
-    }
-
-    // Output and Close FPA
-    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
-        ESCAPE("save failure for FPA");
-    }
-    psFree(view);
-
-    // Dump configuration
-    psString dump_file = psMetadataLookupStr(&status, config->arguments, "DUMP_CONFIG");
-    if (dump_file) {
-        if (!pmConfigDump(config, dump_file)) {
-            ESCAPE("Unable to dump configuration.");
-        }
-    }
-
-    // Write out summary statistics
-    if (options->doStats) {
-        psMetadataAddF32(stats, PS_LIST_TAIL, "DT_DET", 0, "Time spent detrending (sec)", timeDetrend);
-        psMetadataAddF32(stats, PS_LIST_TAIL, "DT_PHOT", 0, "Time spent photometering (sec)", timePhot);
-        psMetadataAddF32(stats, PS_LIST_TAIL, "DT_TOTAL", 0, "Total time (sec)", psTimerMark(TIMER_TOTAL));
-        if (!ppImageStatsOutput(config, stats, options)) {
-            ESCAPE("Unable to write statistics file.");
-        }
-    }
-    psFree (stats);
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageMaskStats.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageMaskStats.c	(revision 29946)
+++ 	(revision )
@@ -1,92 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-
-bool ppImageMaskStats(pmConfig *config, pmFPAview *view, psMetadata *stats)
-{
-  PS_ASSERT_PTR_NON_NULL(view, false);
-  PS_ASSERT_PTR_NON_NULL(config, false);
-
-  if (!stats) {
-      return true;
-  }
-
-  bool status;
-
-  pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.CHIP");
-  if (!status) {
-    psError(PS_ERR_UNEXPECTED_NULL, true, "PPIMAGE.CHIP file is not defined");
-    return(false);
-  }
-
-  psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, "PPIMAGE");
-
-  psU16 staticMaskVal = psMetadataLookupU32(&status, recipe, "MASKSTAT.STATIC");
-  psU16 magicMaskVal = psMetadataLookupU32(&status, recipe, "MASKSTAT.MAGIC");
-  psU16 dynamicMaskVal = psMetadataLookupU32(&status, recipe, "MASKSTAT.DYNAMIC");
-  psU16 advisoryMaskVal = psMetadataLookupU32(&status, recipe, "MASKSTAT.ADVISORY");
-
-  psS32 Npix_valid = 0;
-  psS32 Npix_static = 0;
-  psS32 Npix_magic = 0;
-  psS32 Npix_dynamic = 0;
-  psS32 Npix_advisory = 0;
-
-  pmChip *chip = pmFPAviewThisChip(view, input->fpa);  // Chip of interest
-  if (!chip) {
-    psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip");
-    return(false);
-  }
-  if (chip->cells->n == 0) {
-    psWarning("Chip has no cells");
-    return(true);
-  }
-  if (chip->cells->n > 1) {
-    psWarning("Chip has %ld cells; only the first will be processed", chip->cells->n);
-  }
-  pmCell *cell = chip->cells->data[0]; // Cell of interest
-  if (!cell || !cell->process || !cell->file_exists) {
-    // Nothing to process
-    return(true);
-  }
-  if (cell->readouts->n == 0) {
-    psWarning("Cell has no readouts");
-    return(true);
-  }
-  if (cell->readouts->n > 1) {
-    psWarning("Cell has %ld readouts; only the first will be processed", cell->readouts->n);
-  }
-  pmReadout *readout = cell->readouts->data[0]; // Readout of interest;
-  if (!readout || !readout->data_exists) {
-    // Nothing to process
-    return(true);
-  }
-
-  psImage *mask = readout->mask;  // Mask of interest;
-  psWarning("In ppImageMaskStats: %d %ld\n",Npix_valid, (long) mask);
-
-  if (!pmSingleImageMaskStats(mask,&Npix_valid,&Npix_static,&Npix_magic,
-                              &Npix_dynamic,&Npix_advisory,
-                              staticMaskVal,magicMaskVal,
-                              dynamicMaskVal,advisoryMaskVal)) {
-    psError(PS_ERR_UNKNOWN, false, "Unable to calculate masks for readout.");
-    return(false);
-  }
-  psMetadataAddS32(stats, PS_LIST_TAIL,"MASKFRAC_NPIX", 0,
-                   "Number of valid pixels", Npix_valid);
-  psMetadataAddF32(stats,PS_LIST_TAIL, "MASKFRAC_STATIC", 0,
-                   "Fraction of pixels statically masked", (float) Npix_static / Npix_valid);
-  psMetadataAddF32(stats,PS_LIST_TAIL, "MASKFRAC_DYNAMIC", 0,
-                   "Fraction of pixels dynamically masked", (float) Npix_dynamic / Npix_valid);
-  psMetadataAddF32(stats,PS_LIST_TAIL, "MASKFRAC_MAGIC", 0,
-                   "Fraction of pixels magically masked", (float) Npix_magic / Npix_valid);
-  psMetadataAddF32(stats,PS_LIST_TAIL, "MASKFRAC_ADVISORY", 0,
-                   "Fraction of pixels masked as an advisory", (float) Npix_advisory / Npix_valid);
-  psWarning("In ppImageMaskStats: %d %f %f %f %f\n",Npix_valid, (float) Npix_static / Npix_valid,
-            (float) Npix_dynamic / Npix_valid, (float) Npix_magic / Npix_valid,
-            (float) Npix_advisory / Npix_valid);
-  return(true);
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageMeasureCrosstalk.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageMeasureCrosstalk.c	(revision 29946)
+++ 	(revision )
@@ -1,187 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-#define ESCAPE(MESSAGE) {				\
-	psError(PS_ERR_UNKNOWN, false, MESSAGE);	\
-	psFree(view);					\
-	return false;					\
-    }
-
-// For the moment, this implementation is VERY GPC-specific
-
-bool ppImageMeasureCrosstalk(pmConfig *config, ppImageOptions *options, pmFPAview *view)
-{
-    bool status;
-    const float CUTOFF = 60000;
-    const int MIN_MATCHED_PIXELS = 500;  // require a significant area of high signal
-    char name[64];
-
-    if (!options->doCrosstalkMeasure) return true;
-
-    psTimerStart("crosstalk");
-
-    // confirm that this camera is GPC1
-
-    // find the currently selected chip
-    pmChip *chip = pmFPAfileThisChip(config->files, view, "PPIMAGE.INPUT");
-    pmFPA *fpa = chip->parent;
-    if (chip->cells->n != 64) return true;
-
-    // for each cell (xyNM), we want to find the pixels with values above a cutoff (40k, 60k, ?)
-    // for all of the other cells in the row (xyJM), we want to measure the (robust) median flux in the pixels
-    // corresponding to the high pixels in xyNM, and compare with the median flux for the cell
-
-    psArray *vectorSet = psArrayAlloc(8);
-    psArray *cellRows = psArrayAlloc(8);
-    psArray *imageRows = psArrayAlloc(8);
-    for (int i = 0; i < 8; i++) {
-	psArray *cellRow = psArrayAlloc(8);
-	cellRows->data[i] = cellRow;
-	psArray *imageRow = psArrayAlloc(8);
-	imageRows->data[i] = imageRow;
-	psVector *vector = psVectorAllocEmpty(100, PS_TYPE_F32);
-	vectorSet->data[i] = vector;
-    }
-
-    // assign the cells to arrays by row and column
-    for (int i = 0; i < chip->cells->n; i++) {
-
-	pmCell *cell = chip->cells->data[i];
-
-	// skip the video cells and empty cells (cell->readouts->n != 1)
-	if (cell->readouts->n != 1) {
-	    psWarning ("Skipping Empty and Video Cell for ppImageCrosstalk");
-	    continue;
-	}
-
-	// place the image from this cell in the 2D array:
-	const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");	    
-	int row = cellName[3] - '0';
-	int col = cellName[2] - '0';
-	assert (row >= 0 && row < 8);
-	assert (col >= 0 && col < 8);
-
-	pmReadout *readout = cell->readouts->data[0];
-	psImage *image = readout->image;
-
-	psArray *cellRow = cellRows->data[row];
-	cellRow->data[col] = psMemIncrRefCounter(cell);
-
-	psArray *imageRow = imageRows->data[row];
-	imageRow->data[col] = psMemIncrRefCounter(image);
-    }
-
-    psVector *sample = NULL;
-    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);
-    psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN);
-
-    // measure the background for each cell
-    for (int row = 0; row < cellRows->n; row++) {
-	psArray *cellRow = cellRows->data[row];
-	psArray *imageRow = imageRows->data[row];
-	for (int col = 0; col < cellRow->n; col++) {
-	    pmCell *cell = cellRow->data[col];
-	    if (!cell) continue;
-	    psImage *image = imageRow->data[col];
-	    if (!image) continue; // XXX assert on this?
-
-	    psStatsInit (stats);
-	    if (!psImageBackground (stats, &sample, image, NULL, 0, rng)) continue;
-	    psMetadataAddF32 (cell->analysis, PS_LIST_TAIL, "XTALK.REF", PS_META_REPLACE, "crosstalk measurement", stats->robustMedian);
-	    // fprintf (stderr, "xtalk.ref (xy%d%d) : %f\n", col, row, stats->robustMedian);
-	}
-    }
-
-    for (int row = 0; row < cellRows->n; row++) {
-	psArray *cellRow = cellRows->data[row];
-	psArray *imageRow = imageRows->data[row];
-	for (int col = 0; col < cellRow->n; col++) {
-	    psImage *image = imageRow->data[col];
-	    if (!image) continue;
-
-	    // initialize the storage vectors
-	    for (int i = 0; i < 8; i++) {
-		psVector *vector = vectorSet->data[i];
-		vector->n = 0;
-	    }
-
-	    int nBright = 0;
-
-	    // generate a vector for each of the other cells in this row
-	    // containing only the pixels for which this cell is > CUTOFF
-	    for (int iy = 0; iy < image->numRows; iy++) {
-		for (int ix = 0; ix < image->numCols; ix++) {
-
-		    if (image->data.F32[iy][ix] < CUTOFF) continue;
-		    nBright ++;
-
-		    // this is a pixel of interest in the target cell; extract the matched pixels
-			
-		    for (int i = 0; i < 8; i++) {
-			if (i == col) continue;
-
-			psImage *matchImage = imageRow->data[i];
-			if (!matchImage) continue;
-
-			psVector *vector = vectorSet->data[i];
-			psVectorAppend (vector, matchImage->data.F32[iy][ix]);
-		    }
-		}
-	    }
-	    // fprintf (stderr, "nBright for xy%d%d : %d\n", col, row, nBright);
-	    if (nBright < MIN_MATCHED_PIXELS) continue;
-
-	    // pmCell *refCell = cellRow->data[col];
-	    // float refBackground = psMetadataLookupF32 (&status, refCell->analysis, "XTALK.REF");
-	    // float swing = CUTOFF - refBackground;
-
-	    // now we need to measure the median for these vectors
-	    for (int i = 0; i < 8; i++) {
-		if (i == col) continue;
-		psVector *vector = vectorSet->data[i];
-		if (vector->n < MIN_MATCHED_PIXELS) continue;
-
-		pmCell *cell = cellRow->data[i];
-		if (!cell) continue; // XXX assert on this?
-
-		psStatsInit (stats);
-		if (!psVectorStats (stats, vector, NULL, NULL, 0)) {
-		    psError(PS_ERR_UNKNOWN, false, "failure to measure stats");
-		    return false;
-		}
-		    
-		float background = psMetadataLookupF32 (&status, cell->analysis, "XTALK.REF");
-		float xtalk = (stats->robustMedian - background) / CUTOFF;
-
-		// Put version information into the header
-		pmHDU *hdu = pmHDUGetHighest(fpa, chip, cell);
-		if (hdu) {
-		    // add this to the PHU header 
-		    snprintf (name, 64, "XT_%d%d_%d%d", col, row, i, row);
-		    psMetadataAddF32 (hdu->header, PS_LIST_TAIL, name, PS_META_REPLACE, "crosstalk measurement", xtalk);
-		}
-
-		// keyword for resulting value:
-		snprintf (name, 64, "XTALK_%d%d", i, row);
-
-		psMetadataAddF32 (cell->analysis, PS_LIST_TAIL, name, PS_META_REPLACE, "crosstalk measurement", xtalk);
-		// fprintf (stderr, "xtalk (xy%d%d on xy%d%d) : %f -> delta is %f, slope if %e\n", col, row, i, row, stats->robustMedian, stats->robustMedian - background, xtalk);
-	    }
-	}
-    }
-    psLogMsg ("ppImage", 3, "crosstalk measurement: %f sec\n", psTimerMark ("crosstalk"));
-
-    psFree (vectorSet);
-    psFree (cellRows);
-    psFree (imageRows);
-    psFree (stats);
-    psFree (rng);
-    psFree (sample);
-
-    // need to free all sorts of things here....
-    return true;
-}
-
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageMemory.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageMemory.c	(revision 29946)
+++ 	(revision )
@@ -1,38 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <pslib.h>
-
-#include "ppImage.h"
-
-//#define TESTING
-
-void ppImageMemoryDump(const char *description)
-{
-#ifndef TESTING
-    return;
-#else
-    psMemBlock **leaks = NULL;
-    int numLeaks = psMemCheckLeaks(0, &leaks, NULL, true);
-
-    static int num = 0;
-    psString filename = NULL;
-    psStringAppend(&filename, "%s_%d.txt", description, num++);
-    FILE *fp = fopen(filename, "w");
-    psFree(filename);
-
-    for (int i = 0; i < numLeaks; i++) {
-        psMemBlock *memBlock = leaks[i];
-        fprintf(fp, "%ld : %s at (%s:%d)  ID: %lu  Ref: %lu\n",
-                (unsigned long)memBlock->userMemorySize, memBlock->func, memBlock->file,
-                (int)memBlock->lineno, (unsigned long)memBlock->id, memBlock->refCounter);
-    }
-    psFree(leaks);
-
-    fclose(fp);
-
-    return;
-#endif
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageMetadataStats.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageMetadataStats.c	(revision 29946)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-// calculate stats from headers and concepts
-bool ppImageMetadataStats(pmConfig *config, psMetadata *stats, const ppImageOptions *options)
-{
-    bool mdok;              // Status of MD lookup
-
-    if (!options->doStats) {
-        return true;
-    }
-
-    // Extract statistics from the last output fpa
-    pmFPAfile *outImage  = psMetadataLookupPtr(&mdok, config->files, "PPIMAGE.OUTPUT");
-    pmFPAfile *outPhotom = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.OUTPUT");
-    pmFPAfile *outAstrom = psMetadataLookupPtr(&mdok, config->files, "PSASTRO.OUTPUT");
-
-    if (!outImage && !outPhotom && !outAstrom) {
-        psError(PS_ERR_UNEXPECTED_NULL, true,
-                "Unable to find any output file (PPIMAGE.OUTPUT, PSPHOT.OUTPUT, PSASTRO.OUTPUT).");
-        return false;
-    }
-
-    // get the latest output product available
-    pmFPAfile *output = outAstrom;
-    if (!output) {
-        output = outPhotom;
-    }
-    if (!output) {
-        output = outImage;
-    }
-
-    // extract stats for the complete fpa
-    pmFPAview *view = pmFPAviewAlloc(0);
-    if (!ppStatsMetadata(stats, output->fpa, view, options->maskValue, config)) {
-        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate stats for image.");
-        psFree(view);
-        return false;
-    }
-
-    psFree(view);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageMosaic.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageMosaic.c	(revision 29946)
+++ 	(revision )
@@ -1,103 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageMosaicChip(pmConfig *config, const ppImageOptions *options, const pmFPAview *view,
-                       const char *outFile, const char *inFile)
-{
-    bool status;                        // Status of MD lookup
-
-    pmFPAfile *in = psMetadataLookupPtr(&status, config->files, inFile); // Input file
-    if (!status) {
-        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
-        exit(EXIT_FAILURE);
-    }
-
-    pmFPAfile *out = psMetadataLookupPtr(&status, config->files, outFile); // Output file
-    if (!status) {
-        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
-        exit(EXIT_FAILURE);
-    }
-
-    pmChip *outChip = pmFPAviewThisChip(view, out->fpa);
-    pmChip *inChip = pmFPAviewThisChip(view, in->fpa);
-    if (!outChip->hdu && !outChip->parent->hdu) {
-        pmFPAAddSourceFromView(out->fpa, view, out->format);
-    }
-
-    // If the input is a dark (normalising and mosaicking) then it looks like a video cell and will be ignored
-    // by pmChipMosaic.  We therefore hack the structure so it doesn't look like a video cell.
-    psVector *darkNumbers = NULL;       // Number of dark readouts for each cell
-    if (psMetadataLookupBool(&status, config->arguments, "INPUT_IS_DARK")) {
-        darkNumbers = psVectorAlloc(inChip->cells->n, PS_TYPE_S32);
-	psVectorInit(darkNumbers, 0);
-        for (int i = 0; i < inChip->cells->n; i++) {
-            pmCell *cell = inChip->cells->data[i];
-            if (!cell) {
-                continue;
-            }
-            darkNumbers->data.S32[i] = cell->readouts->n;
-            cell->readouts->n = 1;
-        }
-    }
-
-    psTrace("pmChipMosaic", 5, "mosaic chip %s to %s (xbin,ybin: %d,%d to %d,%d)\n",
-            in->name, out->name, in->xBin, in->yBin, out->xBin, out->yBin);
-
-    // Mosaic the chip, making a deep copy.  This has the side effect of making the output
-    // image products pure trimmed images, but also increases the memory footprint.
-    status = pmChipMosaic(outChip, inChip, true, options->blankMask);
-
-    // Restore dark structure
-    if (darkNumbers) {
-        for (int i = 0; i < inChip->cells->n; i++) {
-            pmCell *cell = inChip->cells->data[i];
-            if (!cell) {
-                continue;
-            }
-            cell->readouts->n = darkNumbers->data.S32[i];
-        }
-        psFree(darkNumbers);
-    }
-
-    return status;
-}
-
-bool ppImageMosaicFPA (pmConfig *config, const ppImageOptions *options, const char *outFile,
-                       const char *inFile)
-{
-    bool status;                        // Status of MD lookup
-
-    pmFPAfile *in = psMetadataLookupPtr(&status, config->files, inFile); // Input file
-    if (!status) {
-        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
-        exit(EXIT_FAILURE);
-    }
-
-    pmFPAfile *out = psMetadataLookupPtr(&status, config->files, outFile); // Output file
-    if (!status) {
-        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
-        exit(EXIT_FAILURE);
-    }
-
-    // XXX test printing of all concepts
-    #if 0
-    for (int i = 0; i < in->fpa->chips->n; i++) {
-        pmChip *chip = in->fpa->chips->data[i];
-        for (int j = 0; j < chip->cells->n; j++) {
-            pmCell *cell = chip->cells->data[j];
-            psMetadataPrint(stdout, cell->concepts, 2);
-        }
-    }
-    #endif
-
-    pmFPAview *view = pmFPAviewAlloc(0);
-    pmFPAAddSourceFromView(out->fpa, view, out->format);
-    psFree(view);
-
-    psTrace ("pmFPAMosaic", 5, "mosaic fpa %s to %s (xbin,ybin: %d,%d to %d,%d)\n",
-             in->name, out->name, in->xBin, in->yBin, out->xBin, out->yBin);
-    return pmFPAMosaic(out->fpa, in->fpa, false, options->blankMask);
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageOptions.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageOptions.c	(revision 29946)
+++ 	(revision )
@@ -1,346 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-static void imageOptionsFree(ppImageOptions *options)
-{
-    psFree(options->overscan);
-    // psFree(options->nonLinearData);
-    // psFree(options->nonLinearSource);
-}
-
-ppImageOptions *ppImageOptionsAlloc(void)
-{
-    ppImageOptions *options = psAlloc(sizeof(ppImageOptions));
-    psMemSetDeallocator(options, (psFreeFunc)imageOptionsFree);
-
-    // actions which ppImage should perform
-    options->doMaskBuild     = false;   // Build internal mask
-    options->doMaskSat       = false;   // mask saturated pixels
-    options->doMaskLow       = false;   // mask low pixels
-    options->doMaskBurntool  = false;   // mask potential burntool trails
-    options->doVarianceBuild = false;   // Build internal variance
-    options->doMask          = false;   // Mask bad pixels
-    options->doNonLin        = false;   // Non-linearity correction
-    options->doOverscan      = false;   // Overscan subtraction
-    options->doNoiseMap      = false;   // Apply Read Noise Map
-    options->doBias          = false;   // Bias subtraction
-    options->doDark          = false;   // Dark subtraction
-    options->doRemnance      = false;   // Remnance masking
-    options->doShutter       = false;   // Shutter correction
-    options->doFlat          = false;   // Flat-field normalisation
-    options->doPatternRow    = false;   // Row pattern correction
-    options->doPatternCell   = false;   // Cell pattern correction
-    options->doFringe        = false;   // Fringe subtraction
-    options->doPhotom        = false;   // Source identification and photometry
-    options->doAstromChip    = false;   // Astrometry (per-chip)
-    options->doAstromMosaic  = false;   // Astrometry (full-mosaic)
-    options->doStats         = false;   // Measure and save image statistics
-    options->checkCTE        = false;   // Measure pixel-based variance
-    options->applyParity     = false;   // Apply Cell parities
-    options->doMaskStats     = false;   // Calculate mask fractions
-    
-    // output files requested
-    options->BaseFITS        = false;   // create output image
-    options->BaseMaskFITS    = false;   // create output mask image
-    options->BaseVarianceFITS  = false;   // create output variance image
-
-    options->ChipFITS        = false;   // create output chip-mosaic image
-    options->ChipMaskFITS    = false;   // create output chip-mosaic mask image
-    options->ChipVarianceFITS  = false;   // create output chip-mosaic variance image
-
-    options->FPA1FITS        = false;   // create fpa-mosaic binned image (scale 1)
-    options->FPA2FITS        = false;   // create fpa-mosaic binned image (scale 2)
-    options->Bin1FITS        = false;   // create binned image (scale 1)
-    options->Bin2FITS        = false;   // create binned image (scale 2)
-    options->Bin1JPEG        = false;   // create jpeg of binned image (scale 1)
-    options->Bin2JPEG        = false;   // create jpeg of binned image (scale 2)
-
-    // default flags for various activities
-    options->maskValue       = 0x00;    // Default mask value (used to skip / ignore pixels)
-    options->satMask         = 0x00;    // Saturated pixels (supplied to pmReadoutGenerateMask)
-    options->lowMask         = 0x00;    // out-of-bounds (low) pixels (supplied to pmReadoutGenerateMask)
-    options->flatMask        = 0x00;    // Bad flat pixels (supplied to pmFlatField)
-    options->darkMask        = 0x00;    // Bad dark pixels (supplied to pmDarkApply)
-    options->blankMask       = 0x00;    // Blank (no data, cell gap) pixels (supplied to pmChipMosaic, pmFPAMosaic)
-    options->markValue       = 0x00;    // A safe bit for internal marking
-    options->burntoolMask    = 0x00;    // Suspect pixels that fall where a burntool trail is expected.
-    options->burntoolTrails  = 0x07;    // Which types of burntool areas to mask.
-    // crosstalk options
-    options->doCrosstalkMeasure = false;   // measure crosstalk
-    options->doCrosstalkCorrect = false;   // correct crosstalk
-
-    // Non-linearity default options
-    options->nonLinearType   = 0;       // Type of non-linearity data (vector, string or metadata)
-    options->nonLinearData   = NULL;    // The non-linearity data
-    options->nonLinearSource = NULL;    // If the non-linearity data is a menu, this provides the key
-
-    // Overscan defaults
-    options->overscan        = NULL;    // Overscan options
-
-    // binning parameters
-    options->xBin1           = 16;      // x-binning, scale 1
-    options->yBin1           = 16;      // y-binning, scale 1
-    options->xBin2           = 16;      // x-binning, scale 2
-    options->yBin2           = 16;      // y-binning, scale 2
-
-    // Fringe defaults
-    options->fringeRej       = NAN;     // Fringe rejection limit
-    options->fringeIter      = 0;       // Fringe iterations
-    options->fringeKeep      = 1.0;     // Fringe keep fraction
-
-    // Pattern correction values
-
-    options->patternRowOrder    = 0;       // Polynomial order
-    options->patternRowIter     = 0;       // Clipping iterations
-    options->patternRowRej      = NAN;     // Clipping rejection threshold
-    options->patternRowThresh   = NAN;     // Threshold for ignoring pixels
-    options->patternRowMean     = PS_STAT_NONE; // Statistic for mean
-    options->patternRowStdev    = PS_STAT_NONE; // Statistic for standard deviation
-    options->patternCellBG      = PS_STAT_NONE; // Statistic for background
-    options->patternCellMean    = PS_STAT_NONE; // Statistic for mean
-
-    // Remnance values
-    options->remnanceSize    = 30;      // Size for remnance detection
-    options->remnanceThresh  = 25.0;    // Threshold for remnance detection
-
-    // per-class normalization source
-    options->normClass       = NULL;    // per-class normalizations refer to this class
-
-    return options;
-}
-
-ppImageOptions *ppImageOptionsParse(pmConfig *config)
-{
-    bool status;
-    ppImageOptions *options = ppImageOptionsAlloc ();
-
-    // select the recipe for this analysis
-    bool mdStatus = false;              // Result of MD lookup
-    psMetadata *recipe = psMetadataLookupMetadata(&mdStatus, config->recipes, RECIPE_NAME);
-    if (! mdStatus || !recipe) {
-        psLogMsg("ppImage", PS_LOG_ERROR, "Can't find recipe %s in the RECIPES.\n", RECIPE_NAME);
-        exit(EXIT_FAILURE);
-    }
-
-    // Non-linearity recipe options
-    if (psMetadataLookupBool(NULL, recipe, "NONLIN")) {
-        psMetadataItem *dataItem = psMetadataLookup(recipe, "NONLIN.DATA");
-        if (! dataItem) {
-            psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.DATA in recipe %s.", RECIPE_NAME);
-            exit(EXIT_FAILURE);
-        }
-
-        options->doNonLin = true;
-        options->nonLinearType = dataItem->type;
-        options->nonLinearData = dataItem;
-
-        switch (dataItem->type) {
-            // No immediate action required
-          case PS_DATA_VECTOR:
-          case PS_DATA_STRING:
-            break;
-
-            // This is a menu; we need the key
-          case PS_DATA_METADATA:
-	    options->nonLinearSource = psMetadataLookupStr(&status, recipe, "NONLIN.SOURCE");
-	    if (! status || ! options->nonLinearSource) {
-		psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.SOURCE in recipe %s.", RECIPE_NAME);
-		exit(EXIT_FAILURE);
-	    }
-            break;
-          default:
-            psLogMsg("ppImage", PS_LOG_ERROR, "Non-linearity correction desired, but NONLIN.DATA is of invalid type in recipe %s.", RECIPE_NAME);
-            exit(EXIT_FAILURE);
-        }
-    }
-
-    // XXX PAP: The overscan stuff needs to be updated following the reworked API
-
-    // Overscan recipe options
-    // XXX EAM : we should abort on invalid options. default options?
-    if (psMetadataLookupBool(NULL, recipe, "OVERSCAN")) {
-        options->doOverscan = true;
-
-        // Do the overscan as a single value?
-        bool overscanSingle = psMetadataLookupBool(NULL, recipe, "OVERSCAN.SINGLE");
-
-        // How do we fit it?
-        pmFit overscanFit = PM_FIT_NONE; // Fit type for overscan
-        int overscanOrder = 0;          // Order for overscan fit
-        psString fit = psMetadataLookupStr(NULL, recipe, "OVERSCAN.FIT");
-        if (! strcasecmp(fit, "POLYNOMIAL")) {
-            overscanFit = PM_FIT_POLY_ORD;
-            overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
-        } else if (! strcasecmp(fit, "CHEBYSHEV")) {
-            overscanFit = PM_FIT_POLY_CHEBY;
-            overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
-        } else if (! strcasecmp(fit, "SPLINE")) {
-            overscanFit = PM_FIT_SPLINE;
-        } else if (strcasecmp(fit, "NONE")) {
-            psLogMsg(__func__, PS_LOG_WARN,
-                     "OVERSCAN.FIT (%s) in recipe %s is not one of NONE, POLYNOMIAL, or SPLINE",
-                     fit, RECIPE_NAME);
-            exit(EXIT_FAILURE);
-        }
-
-        // What method do we use to measure the overscan statistics?
-        // XXX allow user to specify psStats types by name
-        psStats *overscanStats = NULL;  // Statistics for overscan
-        psString stat = psMetadataLookupStr(NULL, recipe, "OVERSCAN.STAT");
-        if (! strcasecmp(stat, "MEAN")) {
-            // overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-            overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-        } else if (! strcasecmp(stat, "MEDIAN")) {
-            overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
-        } else {
-            psErrorStackPrint(stderr, "OVERSCAN.STAT (%s) in recipe %s is not one of MEAN or MEDIAN",
-                              stat, RECIPE_NAME);
-            exit(EXIT_FAILURE);
-        }
-
-        int boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.BOXCAR");
-        float gauss = psMetadataLookupF32(NULL, recipe, "OVERSCAN.GAUSS");
-
-        // Fill in the options
-        options->overscan = pmOverscanOptionsAlloc(overscanSingle, overscanFit, overscanOrder,
-                                                   overscanStats, boxcar, gauss);
-
-        options->overscan->constant = psMetadataLookupBool(NULL, recipe, "OVERSCAN.CONSTANT");
-        options->overscan->value = psMetadataLookupF32(NULL, recipe, "OVERSCAN.VALUE");
-
-        psFree(overscanStats);
-    }
-
-    // for these images, even if not required otherwise
-    options->doMaskBuild = psMetadataLookupBool(NULL, recipe, "MASK.BUILD");
-    options->doMaskSat   = psMetadataLookupBool(NULL, recipe, "MASK.SATURATED");
-    options->doMaskLow   = psMetadataLookupBool(NULL, recipe, "MASK.LOW");
-    options->doMaskBurntool = psMetadataLookupBool(NULL, recipe, "MASK.BURNTOOL");
-    options->doVarianceBuild = psMetadataLookupBool(NULL, recipe, "VARIANCE.BUILD");
-
-    // Mask recipe options (note that mask bit values are set in ppImageSetMaskBits.c)
-    options->doMask = psMetadataLookupBool(NULL, recipe, "MASK");
-
-    // Mask recipe options (note that mask bit values are set in ppImageSetMaskBits.c)
-    options->doCrosstalkMeasure = psMetadataLookupBool(NULL, recipe, "CROSSTALK.MEASURE");
-    options->doCrosstalkCorrect = psMetadataLookupBool(NULL, recipe, "CROSSTALK.CORRECT");
-
-    options->doNoiseMap = psMetadataLookupBool(NULL, recipe, "NOISEMAP");
-    options->doBias = psMetadataLookupBool(NULL, recipe, "BIAS");
-    options->doDark = psMetadataLookupBool(NULL, recipe, "DARK");
-    options->doRemnance = psMetadataLookupBool(NULL, recipe, "REMNANCE");
-    options->doFlat = psMetadataLookupBool(NULL, recipe, "FLAT");
-    options->doFringe = psMetadataLookupBool(NULL, recipe, "FRINGE");
-    options->doShutter = psMetadataLookupBool(NULL, recipe, "SHUTTER");
-    options->doPatternRow = psMetadataLookupBool(NULL, recipe, "PATTERN.ROW");
-    options->doPatternCell = psMetadataLookupBool(NULL, recipe, "PATTERN.CELL");
-    options->doMaskStats = psMetadataLookupBool(NULL, recipe, "MASK.STATS");
-
-    options->doStats = false;
-    char *statsName = psMetadataLookupStr(&status, config->arguments, "STATS"); // Filename for statistics
-    if (statsName) {
-        options->doStats = true;
-    }
-
-    options->applyParity = psMetadataLookupBool(NULL, recipe, "APPLY.CELL.PARITY");
-
-    options->burntoolTrails = psMetadataLookupS32(&status, recipe, "BURNTOOL.TRAILS");
-    psTrace("psModules.detrend", 7, "burntoolTrails: %d BURNTOOL.TRAILS: %d Status: %d\n",
-            options->burntoolTrails,psMetadataLookupS32(&status,recipe,"BURNTOOL.TRAILS"),status);
-    if (!status) {
-      psWarning("BURNTOOL.TRAILS not found in recipe: setting to default value.\n");
-    }
-
-    // binned image options
-    options->xBin1 = psMetadataLookupS32(&status, recipe, "BIN1.XBIN");
-    if (!status) {
-        psWarning("BIN1.XBIN not found in recipe: setting to default value.\n");
-        options->xBin1 = 4;
-    }
-    options->yBin1 = psMetadataLookupS32(&status, recipe, "BIN1.YBIN");
-    if (!status) {
-        psWarning("BIN1.YBIN not found in recipe: setting to default value.\n");
-        options->yBin1 = 4;
-    }
-
-    options->xBin2 = psMetadataLookupS32(&status, recipe, "BIN2.XBIN");
-    if (!status) {
-        psWarning("BIN2.XBIN not found in recipe: setting to default value.\n");
-       options->xBin1 = 16;
-    }
-    options->yBin2 = psMetadataLookupS32(&status, recipe, "BIN2.YBIN");
-    if (!status) {
-        psWarning("BIN2.YBIN not found in recipe: setting to default value.\n");
-        options->yBin1 = 16;
-    }
-
-    options->BaseFITS       = psMetadataLookupBool(NULL, recipe, "BASE.FITS");
-    options->BaseMaskFITS   = psMetadataLookupBool(NULL, recipe, "BASE.MASK.FITS");
-    options->BaseVarianceFITS = psMetadataLookupBool(NULL, recipe, "BASE.VARIANCE.FITS");
-
-    options->ChipFITS       = psMetadataLookupBool(NULL, recipe, "CHIP.FITS");
-    options->ChipMaskFITS   = psMetadataLookupBool(NULL, recipe, "CHIP.MASK.FITS");
-    options->ChipVarianceFITS = psMetadataLookupBool(NULL, recipe, "CHIP.VARIANCE.FITS");
-
-    options->FPA1FITS       = psMetadataLookupBool(NULL, recipe, "FPA1.FITS");
-    options->FPA2FITS       = psMetadataLookupBool(NULL, recipe, "FPA2.FITS");
-
-    options->Bin1FITS       = psMetadataLookupBool(NULL, recipe, "BIN1.FITS");
-    options->Bin1JPEG       = psMetadataLookupBool(NULL, recipe, "BIN1.JPEG");
-    options->Bin2FITS       = psMetadataLookupBool(NULL, recipe, "BIN2.FITS");
-    options->Bin2JPEG       = psMetadataLookupBool(NULL, recipe, "BIN2.JPEG");
-
-    options->doPhotom       = psMetadataLookupBool(NULL, recipe, "PHOTOM");
-    options->doAstromChip   = psMetadataLookupBool(NULL, recipe, "ASTROM.CHIP");
-    options->doAstromMosaic = psMetadataLookupBool(NULL, recipe, "ASTROM.MOSAIC");
-    options->doBG           = psMetadataLookupBool(NULL, recipe, "BACKGROUND");
-
-    options->checkCTE       = psMetadataLookupBool(NULL, recipe, "CHECK.CTE");
-
-    // even if not requested explicitly, if any of these are set, build an internal mask and variance:
-    if (options->doNoiseMap || options->doBias || options->doOverscan || options->doDark || options->doShutter || options->doFlat ||
-        options->doPhotom) {
-        options->doMaskBuild = true;
-        options->doVarianceBuild = true;
-    } else if (options->doMask || options->doBG) {
-        options->doMaskBuild = true;
-    }
-
-    if ((options->doAstromChip || options->doAstromMosaic) && !options->doPhotom) {
-        psLogMsg(__func__, PS_LOG_ERROR, "Invalid PPIMAGE options: cannot do ASTROMetry without PHOTOMetry");
-        exit(EXIT_FAILURE);
-    }
-
-    // Fringe options
-    options->fringeRej = psMetadataLookupF32(NULL, recipe, "FRINGE.REJ");
-    options->fringeIter = psMetadataLookupS32(NULL, recipe, "FRINGE.ITER");
-    options->fringeKeep = psMetadataLookupF32(NULL, recipe, "FRINGE.KEEP");
-
-    // Pattern correction
-    options->patternRowOrder = psMetadataLookupS32(NULL, recipe, "PATTERN.ROW.ORDER");
-    options->patternRowIter = psMetadataLookupS32(NULL, recipe, "PATTERN.ROW.ITER");
-    options->patternRowRej = psMetadataLookupF32(NULL, recipe, "PATTERN.ROW.REJ");
-    options->patternRowThresh = psMetadataLookupF32(NULL, recipe, "PATTERN.ROW.THRESH");
-    options->patternRowMean = psStatsOptionFromString(psMetadataLookupStr(NULL, recipe, "PATTERN.ROW.MEAN"));
-    options->patternRowStdev = psStatsOptionFromString(psMetadataLookupStr(NULL, recipe, "PATTERN.ROW.STDEV"));
-    options->patternCellBG = psStatsOptionFromString(psMetadataLookupStr(NULL, recipe, "PATTERN.CELL.BG"));
-    options->patternCellMean = psStatsOptionFromString(psMetadataLookupStr(NULL, recipe, "PATTERN.CELL.MEAN"));
-
-    // Remnance options
-    options->remnanceSize = psMetadataLookupF32(NULL, recipe, "REMNANCE.SIZE");
-    options->remnanceThresh = psMetadataLookupS32(NULL, recipe, "REMNANCE.THRESH");
-
-    // per-class normalization source (just a reference; don't free)
-    options->normClass = psMetadataLookupStr(NULL, recipe, "NORM.CLASS");
-
-    options->maskstat_static   = psMetadataLookupU16(NULL, recipe, "MASKSTAT.STATIC");
-    options->maskstat_dynamic  = psMetadataLookupU16(NULL, recipe, "MASKSTAT.DYNAMIC");
-    options->maskstat_magic    = psMetadataLookupU16(NULL, recipe, "MASKSTAT.MAGIC");
-    options->maskstat_advisory = psMetadataLookupU16(NULL, recipe, "MASKSTAT.ADVISORY");
-
-    
-    return options;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageParityFlip.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageParityFlip.c	(revision 29946)
+++ 	(revision )
@@ -1,162 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-// Update a concept to the assumed value
-#define FIX_CONCEPT(SOURCE, NAME, TYPE, VALUE) {        \
-psMetadataItem *item = psMetadataLookup(SOURCE, NAME); \
-item->data.TYPE = VALUE; }
-
-// flip the image to have 'native' (detector) or 'raw' (readout) orientation 
-bool ppImageParityFlip (pmConfig *config, const ppImageOptions *options, const pmFPAview *view, bool native) {
-
-    bool status;
-    int xParity, yParity;
-    int xParityRaw, yParityRaw;
-    int xParityTarget, yParityTarget;
-
-    if (!options->applyParity) return true;
-
-    // find the currently selected readout
-    pmReadout *readout = pmFPAfileThisReadout(config->files, view, "PPIMAGE.INPUT");
-
-    pmCell *cell = readout->parent;
-
-    if (native) {
-	// find the current (raw) parity
-	xParity = psMetadataLookupS32(&status, cell->concepts, "CELL.XPARITY");
-	if (!status || (xParity != -1 && xParity != 1)) {
-	    psWarning("CELL.XPARITY is not set for the input cell; assuming 1.\n");
-	    FIX_CONCEPT(cell->concepts, "CELL.XPARITY", S32, 1);
-	    xParity = 1;
-	}
-	yParity = psMetadataLookupS32(&status, cell->concepts, "CELL.YPARITY");
-	if (!status || (yParity != -1 && yParity != 1)) {
-	    psWarning("CELL.YPARITY is not set for the input cell; assuming 1.\n");
-	    FIX_CONCEPT(cell->concepts, "CELL.YPARITY", S32, 1);
-	    yParity = 1;
-	}
-
-	// save the raw parity
-	psMetadataAddS32 (cell->concepts, PS_LIST_TAIL, "CELL.XPARITY.RAW", PS_META_REPLACE, "original parity", xParity);
-	psMetadataAddS32 (cell->concepts, PS_LIST_TAIL, "CELL.YPARITY.RAW", PS_META_REPLACE, "original parity", yParity);
-
-	xParityTarget = 1;
-	yParityTarget = 1;
-    } else {
-	// find the current (native) parity
-	xParity = psMetadataLookupS32(&status, cell->concepts, "CELL.XPARITY");
-	psAssert (status, "CELL.XPARITY not set : cannot call ppImageParityFlip (native = false) without first calling it with native = true");
-
-	yParity = psMetadataLookupS32(&status, cell->concepts, "CELL.YPARITY");
-	psAssert (status, "CELL.YPARITY not set : cannot call ppImageParityFlip (native = false) without first calling it with native = true");
-
-	// find the raw parity
-	xParityRaw = psMetadataLookupS32(&status, cell->concepts, "CELL.XPARITY.RAW");
-	psAssert (status, "CELL.XPARITY not set : cannot call ppImageParityFlip (native = false) without first calling it with native = true");
-
-	yParityRaw = psMetadataLookupS32(&status, cell->concepts, "CELL.YPARITY.RAW");
-	psAssert (status, "CELL.YPARITY not set : cannot call ppImageParityFlip (native = false) without first calling it with native = true");
-
-	xParityTarget = xParityRaw;
-	yParityTarget = yParityRaw;
-    }
-
-    // for this case, nothing to be done:
-    if ((xParity == xParityTarget) && (yParity == yParityTarget)) return true;
-
-    psImage *image = readout->image;
-    psImage *var   = readout->variance;
-    psImage *mask  = readout->mask;
-
-    if (var) psAssert (image->numCols == var->numCols,  "image and variance sizes are mismatched");
-    if (var) psAssert (image->numRows == var->numRows,  "image and variance sizes are mismatched");
-    if (mask) psAssert (image->numCols == mask->numCols, "image and mask sizes are mismatched");
-    if (mask) psAssert (image->numRows == mask->numRows, "image and mask sizes are mismatched");
-
-    int Nx = image->numCols;
-    int Ny = image->numRows;
-
-    // we need working buffers for the image, variance, and mask:
-    psF32 *imrow = (psF32 *) psAlloc (Nx*sizeof(psF32));
-    psF32 *wtrow = (psF32 *) psAlloc (Nx*sizeof(psF32));
-    psImageMaskType *mkrow = (psImageMaskType *) psAlloc (Nx*sizeof(psImageMaskType));
-
-    // the three cases (+1,-1), (-1,+1), (-1,-1) should be handled independently
-
-    // flip only in x-direction
-    if ((xParity != xParityTarget) && (yParity == yParityTarget)) {
-	for (int iy = 0; iy < Ny; iy++) {
-	    for (int ix = 0; ix < Nx; ix++) {
-		imrow[Nx-1-ix] = image->data.F32[iy][ix];
-	    }
-	    for (int ix = 0; (var != NULL) && (ix < Nx); ix++) {
-		wtrow[Nx-1-ix] = var->data.F32[iy][ix];
-	    }
-	    for (int ix = 0; (mask != NULL) && (ix < Nx); ix++) {
-		mkrow[Nx-1-ix] = mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix];
-	    }
-	    memcpy (image->data.F32[iy], imrow, Nx*sizeof(psF32));
-	    if (var) memcpy (var->data.F32[iy],   wtrow, Nx*sizeof(psF32));
-	    if (mask) memcpy (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy], mkrow, Nx*sizeof(psImageMaskType));
-	}
-    }
-    // flip only in y-direction
-    if ((xParity == xParityTarget) && (yParity != yParityTarget)) {
-	for (int iy = 0; iy < Ny/2; iy++) {
-	    memcpy (imrow, image->data.F32[iy], Nx*sizeof(psF32));
-	    memcpy (image->data.F32[iy], image->data.F32[Ny-1-iy], Nx*sizeof(psF32));
-	    memcpy (image->data.F32[Ny-1-iy], imrow, Nx*sizeof(psF32));
-
-	    if (var) {
-		memcpy (wtrow, var->data.F32[iy], Nx*sizeof(psF32));
-		memcpy (var->data.F32[iy], var->data.F32[Ny-1-iy], Nx*sizeof(psF32));
-		memcpy (var->data.F32[Ny-1-iy], wtrow, Nx*sizeof(psF32));
-	    }
-
-	    if (mask) {
-		memcpy (mkrow, mask->data.PS_TYPE_IMAGE_MASK_DATA[iy], Nx*sizeof(psImageMaskType));
-		memcpy (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy], mask->data.PS_TYPE_IMAGE_MASK_DATA[Ny-1-iy], Nx*sizeof(psImageMaskType));
-		memcpy (mask->data.PS_TYPE_IMAGE_MASK_DATA[Ny-1-iy], mkrow, Nx*sizeof(psImageMaskType));
-	    }
-	}
-    }
-    // flip in both directions
-    if ((xParity != xParityTarget) && (yParity != yParityTarget)) {
-	for (int iy = 0; iy < Ny/2; iy++) {
-	    for (int ix = 0; ix < Nx; ix++) {
-		imrow[Nx-1-ix] = image->data.F32[iy][ix];
-	    }
-	    for (int ix = 0; var && (ix < Nx); ix++) {
-		wtrow[Nx-1-ix] = var->data.F32[iy][ix];
-	    }
-	    for (int ix = 0; mask && (ix < Nx); ix++) {
-		mkrow[Nx-1-ix] = mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix];
-	    }
-
-	    for (int ix = 0; ix < Nx; ix++) {
-		image->data.F32[iy][Nx-1-ix] = image->data.F32[Ny-1-iy][ix];
-	    }
-	    for (int ix = 0; var && (ix < Nx); ix++) {
-		var->data.F32[iy][Nx-1-ix] = var->data.F32[Ny-1-iy][ix];
-	    }
-	    for (int ix = 0; mask && (ix < Nx); ix++) {
-		mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][Nx-1-ix] = mask->data.PS_TYPE_IMAGE_MASK_DATA[Ny-1-iy][ix];
-	    }
-
-	    memcpy (image->data.F32[Ny-1-iy], imrow, Nx*sizeof(psF32));
-	    if (var) memcpy (var->data.F32[Ny-1-iy], wtrow, Nx*sizeof(psF32));
-	    if (mask) memcpy (mask->data.PS_TYPE_IMAGE_MASK_DATA[Ny-1-iy], mkrow, Nx*sizeof(psImageMaskType));
-	}
-    }
-
-    FIX_CONCEPT(cell->concepts, "CELL.XPARITY", S32, xParityTarget);
-    FIX_CONCEPT(cell->concepts, "CELL.YPARITY", S32, yParityTarget);
-
-    psFree (imrow);
-    psFree (wtrow);
-    psFree (mkrow);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageParseCamera.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageParseCamera.c	(revision 29946)
+++ 	(revision )
@@ -1,480 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-ppImageOptions *ppImageParseCamera(pmConfig *config)
-{
-    bool status = false;
-
-    if (!ppImageDefineFile(config, NULL, "PPIMAGE.INPUT", "INPUT", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_NONE)) {
-        psError(PS_ERR_IO, false, "Can't find an input image source");
-        return NULL;
-    }
-    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.INPUT"); // Input file
-    psAssert(input, "We just put it there!");
-
-    // add recipe options supplied on command line
-    psMetadata *recipe  = psMetadataLookupPtr(&status, config->recipes, RECIPE_NAME);
-
-    // parse the options from the metadata format to the ppImageOptions structure
-    ppImageOptions *options = ppImageOptionsParse(config);
-
-    // 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->doNoiseMap) {
-        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.NOISEMAP", "NOISEMAP",
-                               PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_NOISEMAP)) {
-            psError(PS_ERR_IO, false, "Can't find a noise map image source");
-            psFree(options);
-            return NULL;
-        }
-    }
-    if (options->doBias) {
-        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.BIAS", "BIAS",
-                               PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_BIAS)) {
-            psError(PS_ERR_IO, false, "Can't find a bias image source");
-            psFree(options);
-            return NULL;
-        }
-    }
-    if (options->doDark) {
-        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.DARK", "DARK",
-                               PM_FPA_FILE_DARK, PM_DETREND_TYPE_DARK)) {
-            psError(PS_ERR_IO, false, "Can't find a dark image source");
-            psFree(options);
-            return NULL;
-        }
-    }
-    if (options->doMask) {
-        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.MASK", "MASK",
-                               PM_FPA_FILE_MASK, PM_DETREND_TYPE_MASK)) {
-            psError(PS_ERR_IO, false, "Can't find a mask image source");
-            psFree(options);
-            return NULL;
-        }
-    }
-    if (options->doShutter) {
-        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.SHUTTER", "SHUTTER",
-                               PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_SHUTTER)) {
-            psError(PS_ERR_IO, false, "Can't find a shutter image source");
-            psFree(options);
-            return NULL;
-        }
-    }
-
-    if (options->doFlat) {
-        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.FLAT", "FLAT",
-                               PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_FLAT)) {
-            psError(PS_ERR_IO, false, "Can't find a flat image source");
-            psFree(options);
-            return NULL;
-        }
-    }
-
-    if (options->doNonLin) {
-      if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.LINEARITY", "LINEARITY",
-			     PM_FPA_FILE_LINEARITY, PM_DETREND_TYPE_LINEARITY)) {
-	psError(PS_ERR_IO, false, "Can't find a non-linearity correction source");
-	psFree(options);
-	return NULL;
-      }
-    }
-
-    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS");
-    if (nThreads > 0) {
-        int nScanRows = psMetadataLookupS32(&status, recipe, "SCAN.ROWS");
-        pmDetrendSetThreadTasks(nScanRows);
-    }
-
-    if (options->doPatternRow || options->doPatternCell) {
-        pmFPAfile *outPattern = pmFPAfileDefineOutput(config, input->fpa, "PPIMAGE.PATTERN");
-        if (!outPattern) {
-            psError(PS_ERR_IO, false, _("Unable to generate output file from PPIMAGE.PATTERN"));
-            psFree(options);
-            return NULL;
-        }
-        outPattern->save = true;
-    }
-
-    // fringe frame are only applied for a subset of the filters.
-    // if the filter is one of those identified by a FRINGE.FILTERS metadata entry
-    // in ppImage.config, apply the fringe frame
-    if (options->doFringe) {
-        // determine filter from the concepts
-        const char *filter = psMetadataLookupStr(&status, input->fpa->concepts, "FPA.FILTER");
-        if (!status || !filter || strlen(filter) == 0) {
-            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FPA.FILTER.\n");
-            psFree(options);
-            return NULL;
-        }
-
-        // select FRINGE.FILTERS from the recipe and test if the filter matches
-        // is the mdi saved with psList or string?
-        psMetadataItem *mdi = psMetadataLookup (recipe, "FRINGE.FILTERS");
-        if (mdi == NULL) {
-            // no valid filters for fringe data for this camera
-            options->doFringe = false;
-            goto skip_fringe;
-        }
-        // place entry on a list regardless of type
-        psList *filters = NULL;
-        if (mdi->type == PS_DATA_STRING) {
-            filters = psListAlloc(NULL);
-            psListAdd (filters, PS_LIST_HEAD, mdi);
-        } else if (mdi->type == PS_DATA_METADATA_MULTI) {
-            filters = psMemIncrRefCounter(mdi->data.list);
-        } else {
-            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                    "FRINGE.FILTERS in recipe %s is not of type METADATA", RECIPE_NAME);
-            psFree(options);
-            return NULL;
-        }
-
-        // search through list to find the current filter
-        psListIterator *iter = psListIteratorAlloc (filters, PS_LIST_HEAD, FALSE);
-        options->doFringe = false;
-        for (int i = 0; !options->doFringe && (i < filters->n); i++) {
-            psMetadataItem *item = psListGetAndIncrement (iter);
-            char *validFilter = item->data.V;
-            if (strcmp (validFilter, filter)) continue;
-            options->doFringe = true;
-        }
-        psFree(iter);
-        psFree(filters);
-    }
-skip_fringe:
-    if (options->doFringe) {
-        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.FRINGE", "FRINGE",
-                               PM_FPA_FILE_FRINGE, PM_DETREND_TYPE_FRINGE)) {
-            psError (PS_ERR_IO, false, "Can't find a fringe image source");
-            return NULL;
-        }
-    }
-
-    if (options->checkCTE && false) {
-        int DX = psMetadataLookupS32 (&status, recipe, "CTE.XBIN");
-        int DY = psMetadataLookupS32 (&status, recipe, "CTE.YBIN");
-        pmFPAfile *outCTE = pmFPAfileDefineFromFile (config, input, DX, DY, "PPIMAGE.CTEMAP");
-        if (!outCTE) {
-            psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PPIMAGE.CTEMAP");
-            return false;
-        }
-        outCTE->save = true;
-    }
-
-    // the following files are output targets
-    pmFPAfile *outImage = pmFPAfileDefineOutput(config, input->fpa, "PPIMAGE.OUTPUT");
-    if (!outImage) {
-        psError(PS_ERR_IO, false, _("Unable to generate output file from PPIMAGE.OUTPUT"));
-        psFree(options);
-        return NULL;
-    }
-    if (outImage->type != PM_FPA_FILE_IMAGE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT is not of type IMAGE");
-        psFree(options);
-        return NULL;
-    }
-    pmFPAfile *outMask = pmFPAfileDefineOutput(config, input->fpa, "PPIMAGE.OUTPUT.MASK");
-    if (!outMask) {
-        psError(PS_ERR_IO, false, _("Unable to generate output file from PPIMAGE.OUTPUT.MASK"));
-        psFree(options);
-        return NULL;
-    }
-    if (outMask->type != PM_FPA_FILE_MASK) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.MASK is not of type MASK");
-        psFree(options);
-        return NULL;
-    }
-    pmFPAfile *outVariance = pmFPAfileDefineOutput(config, input->fpa, "PPIMAGE.OUTPUT.VARIANCE");
-    if (!outVariance) {
-        psError(PS_ERR_IO, false, _("Unable to generate output file from PPIMAGE.OUTPUT.VARIANCE"));
-        psFree(options);
-        return NULL;
-    }
-    if (outVariance->type != PM_FPA_FILE_VARIANCE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.VARIANCE is not of type VARIANCE");
-        psFree(options);
-        return NULL;
-    }
-
-    // XXX should these be bound explicitly to the outImage->fpa rather than the input->fpa?
-    pmFPAfile *chipImage = pmFPAfileDefineChipMosaic(config, input->fpa, "PPIMAGE.CHIP");
-    if (!chipImage) {
-        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.CHIP"));
-        psFree(options);
-        return NULL;
-    }
-    if (chipImage->type != PM_FPA_FILE_IMAGE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.CHIP is not of type IMAGE");
-        psFree(options);
-        return NULL;
-    }
-    pmFPAfile *chipMask = pmFPAfileDefineOutput(config, chipImage->fpa, "PPIMAGE.CHIP.MASK");
-    if (!chipMask) {
-        psError(PS_ERR_IO, false, _("Unable to generate output file from PPIMAGE.CHIP.MASK"));
-        psFree(options);
-        return NULL;
-    }
-    if (chipMask->type != PM_FPA_FILE_MASK) {
-        psError(PS_ERR_IO, true, "PPIMAGE.CHIP.MASK is not of type MASK");
-        psFree(options);
-        return NULL;
-    }
-    pmFPAfile *chipVariance = pmFPAfileDefineOutput(config, chipImage->fpa, "PPIMAGE.CHIP.VARIANCE");
-    if (!chipVariance) {
-        psError(PS_ERR_IO, false, _("Unable to generate output file from PPIMAGE.CHIP.VARIANCE"));
-        psFree(options);
-        return NULL;
-    }
-    if (chipVariance->type != PM_FPA_FILE_VARIANCE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.CHIP.VARIANCE is not of type VARIANCE");
-        psFree(options);
-        return NULL;
-    }
-
-    pmFPAfile *byFPA1 = pmFPAfileDefineFPAMosaic(config, input->fpa, "PPIMAGE.OUTPUT.FPA1");
-    if (!byFPA1) {
-        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.OUTPUT.FPA1"));
-        psFree(options);
-        return NULL;
-    }
-    if (byFPA1->type != PM_FPA_FILE_IMAGE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.FPA1 is not of type IMAGE");
-        psFree(options);
-        return NULL;
-    }
-    pmFPAfile *byFPA2 = pmFPAfileDefineFPAMosaic(config, input->fpa, "PPIMAGE.OUTPUT.FPA2");
-    if (!byFPA2) {
-        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.OUTPUT.FPA2"));
-        psFree(options);
-        return NULL;
-    }
-    if (byFPA2->type != PM_FPA_FILE_IMAGE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.FPA2 is not of type IMAGE");
-        psFree(options);
-        return NULL;
-    }
-
-    // chipImage    -> psphotInput  (pmFPAfileDefineFromFile)       : fpa is constructed
-    // psphotInput  -> psphotOutput (pmFPAfileDefineOutputFromFile) : fpa is equated
-    // psphotOutput -> psastroInput (pmFPAfileDefineInput)          : fpa is ref-copied
-    // psastroInput -> psastroModel (pmFPAfileDefineFromArgs        : fpa is ref-copied
-    // psastroInput -> psastroModel (pmFPAfileDefineFromConf        : fpa is constructed
-    // psastroInput -> psastroModel (pmFPAfileDefineFromDetDB       : fpa is constructed (pmDetrendSelect uses input concepts )
-
-    // For photometry, we operate on the chip-mosaicked image
-    // we create a copy of the mosaicked image for psphot so we can write out a clean image
-    if (options->doPhotom || options->doBG) {
-
-        // this file is just used as a carrier; output files (eg, PSPHOT.RESID) are defined by
-        // psphotDefineFiles
-        pmFPAfile *psphotInput = pmFPAfileDefineFromFile (config, chipImage, 1, 1, "PSPHOT.INPUT");
-        PS_ASSERT (psphotInput, false);
-
-        // specify the number of psphot input images
-        psMetadataAddS32 (config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "number of inputs", 1);
-
-        // define associated psphot input/output files
-        if (!psphotDefineFiles (config, psphotInput)) {
-            psError(PSPHOT_ERR_CONFIG, false,
-                    "Trouble defining the additional input/output files for psphot");
-            return false;
-        }
-    }
-
-    // For photometry, we operate on the chip-mosaicked image
-    if (options->doAstromChip || options->doAstromMosaic) {
-        if (!options->doPhotom) {
-            psError(PSASTRO_ERR_CONFIG, false,
-                    "Photometry mode is not selected; it is required for astrometry");
-            return false;
-        }
-
-        pmFPAfile *psphotOutput = psMetadataLookupPtr(&status, config->files, "PSPHOT.OUTPUT");
-        PS_ASSERT(psphotOutput, false);
-
-        pmFPAfile *psastroInput = pmFPAfileDefineInput(config, psphotOutput->fpa, NULL, "PSASTRO.INPUT");
-        PS_ASSERT(psastroInput, false);
-        psastroInput->mode = PM_FPA_MODE_REFERENCE;
-
-        // define associated psphot input/output files
-        if (!psastroDefineFiles(config, psastroInput)) {
-            psError(PSPHOT_ERR_CONFIG, false,
-                    "Trouble defining the additional input/output files for psastro");
-            return false;
-        }
-
-        // deactivate the psastro files, reactive when needed
-        pmFPAfileActivate(config->files, false, "PSASTRO.OUTPUT");
-    }
-
-    // save any of these files?
-    outImage->save   = options->BaseFITS;
-    outMask->save    = options->BaseMaskFITS;
-    outVariance->save  = options->BaseVarianceFITS;
-
-    chipImage->save  = options->ChipFITS;
-    chipMask->save   = options->ChipMaskFITS;
-    chipVariance->save = options->ChipVarianceFITS;
-
-    byFPA1->save     = options->FPA1FITS;
-    byFPA2->save     = options->FPA2FITS;
-
-    // outImage is used as a carrier: input to chipImage -> require the data to remain at the CHIP level
-    outImage->freeLevel = PS_MIN(outImage->freeLevel, PM_FPA_LEVEL_CHIP);
-    outImage->dataLevel = outImage->freeLevel;
-    outImage->fileLevel = PS_MIN(outImage->fileLevel, outImage->dataLevel);
-
-    // outMask and outVariance must be freed at the same level as outImage (all freed by pmFPAFreeData)
-    outMask->freeLevel   = outImage->freeLevel;
-    outVariance->freeLevel = outImage->freeLevel;
-    outMask->dataLevel   = outImage->dataLevel;
-    outVariance->dataLevel = outImage->dataLevel;
-
-    // Ditto for the chip-mosaicked version
-    chipMask->freeLevel   = chipImage->freeLevel;
-    chipVariance->freeLevel = chipImage->freeLevel;
-    chipMask->dataLevel   = chipImage->dataLevel;
-    chipVariance->dataLevel = chipImage->dataLevel;
-
-    // the input data is the same as the outImage data : force the free levels to match
-    input->freeLevel = PS_MIN(outImage->freeLevel, input->freeLevel);
-
-    // define the binned target files (which may just be carriers for some camera configurations)
-    pmFPAfile *bin1 = pmFPAfileDefineFromFPA(config, chipImage->fpa, options->xBin1, options->yBin1,
-                                             "PPIMAGE.BIN1");
-    if (!bin1) {
-        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.BIN1"));
-        psFree(options);
-        return NULL;
-    }
-    if (bin1->type != PM_FPA_FILE_IMAGE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.BIN1 is not of type IMAGE");
-        psFree(options);
-        return NULL;
-    }
-
-    pmFPAfile *bin2 = pmFPAfileDefineFromFPA(config, chipImage->fpa, options->xBin2, options->yBin2,
-                                             "PPIMAGE.BIN2");
-    if (!bin2) {
-        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.BIN2"));
-        psFree(options);
-        return NULL;
-    }
-    if (bin2->type != PM_FPA_FILE_IMAGE) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.BIN2 is not of type IMAGE");
-        psFree(options);
-        return NULL;
-    }
-
-    // bin1 and bin2 are used as carriers: input for byFPA1, byFPA2
-    bin1->freeLevel = PM_FPA_LEVEL_FPA;
-    bin2->freeLevel = PM_FPA_LEVEL_FPA;
-
-    pmFPAfile *jpg1 = pmFPAfileDefineOutput(config, byFPA1->fpa, "PPIMAGE.JPEG1");
-    if (!jpg1) {
-        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.JPEG1"));
-        psFree(options);
-        return NULL;
-    }
-    if (jpg1->type != PM_FPA_FILE_JPEG) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.JPEG1 is not of type JPEG");
-        psFree(options);
-        return NULL;
-    }
-    pmFPAfile *jpg2 = pmFPAfileDefineOutput(config, byFPA2->fpa, "PPIMAGE.JPEG2");
-    if (!jpg2) {
-        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.JPEG2"));
-        psFree(options);
-        return NULL;
-    }
-    if (jpg2->type != PM_FPA_FILE_JPEG) {
-        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.JPEG2 is not of type JPEG");
-        psFree(options);
-        return NULL;
-    }
-
-    // XXX we could potentially not define these pmFPAfiles if no output is requested...
-    bin1->save = options->Bin1FITS;
-    bin2->save = options->Bin2FITS;
-    jpg1->save = options->Bin1JPEG;
-    jpg2->save = options->Bin2JPEG;
-
-    // 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);
-                psFree(options);
-                return false;
-            }
-        }
-    }
-    psFree (chips);
-
-    if (psMetadataLookupBool(NULL, config->arguments, "INPUT_IS_FRINGE")) {
-        // It's a fringe file, so change the file type
-        input->type = PM_FPA_FILE_FRINGE;
-        outImage->type = PM_FPA_FILE_FRINGE;
-    }
-    if (psMetadataLookupBool(NULL, config->arguments, "INPUT_IS_DARK")) {
-        // It's a dark file, so change the file type
-        input->type = PM_FPA_FILE_DARK;
-        outImage->type = PM_FPA_FILE_DARK;
-        // Turn off compression --- there are just too many nasties that can happen
-        psFree(outImage->compression);
-        outImage->compression = NULL;
-        psFree(outImage->options);
-        outImage->options = NULL;
-    }
-
-    // Turn off mask and variance output if we're not doing anything interesting
-    if (!options->doMaskBuild && outMask->save) {
-        psWarning("output mask image (BASE.MASK.FITS) requested, but not generated: skipping.\n");
-        outMask->save = false;
-    }
-    if (!options->doVarianceBuild && outVariance->save) {
-        psWarning("output variance image (BASE.VARIANCE.FITS) requested, but not generated: skipping.\n");
-        outVariance->save = false;
-    }
-    if (!options->doMaskBuild && chipMask->save) {
-        psWarning("output mask image (CHIP.MASK.FITS) requested, but not generated: skipping.\n");
-        chipMask->save = false;
-    }
-    if (!options->doVarianceBuild && chipVariance->save) {
-        psWarning("output variance image (CHIP.VARIANCE.FITS) requested, but not generated: skipping.\n");
-        chipVariance->save = false;
-    }
-
-    if (psTraceGetLevel("ppImage.config") > 0) {
-        // Get a look inside all the files.
-        psMetadataIterator *filesIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, NULL);
-        psMetadataItem *item;               // Item from iteration
-        fprintf(stderr, "Files:\n");
-        while ((item = psMetadataGetAndIncrement(filesIter))) {
-            pmFPAfile *file = item->data.V; // File of interest
-            fprintf(stderr, "%s: %p %p %p (%p) %p\n", file->name,
-                    file->src, file->fpa,
-                    file->camera, file->fpa->camera, file->format);
-        }
-        psFree(filesIter);
-    }
-
-    // Change the input dark type between the old (IMAGE) and new (multi-DARK).
-    // Hopefully this is a temporary change until we all move over to using the new dark types
-    bool mdok;                          // Status of MD lookup
-    if (options->doDark && psMetadataLookupBool(&mdok, recipe, "OLDDARK")) {
-        pmFPAfile *dark = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.DARK");
-        assert(dark);
-        dark->type = PM_FPA_FILE_IMAGE;
-    }
-
-    return (options);
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImagePhotom.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImagePhotom.c	(revision 29946)
+++ 	(revision )
@@ -1,69 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "ppImage.h"
-
-// In this function, we perform the psphot analysis routine for the chip-mosaicked images
-bool ppImagePhotom(psMetadata *stats, pmConfig *config, pmFPAview *view) {
-
-    bool status;
-    pmCell *cell;
-    pmReadout *readout;
-    printf("%x %s\n",psErrorCodeLast(),psErrorCodeString(psErrorCodeLast()));
-    psphotInit();
-    printf("%x %s\n",psErrorCodeLast(),psErrorCodeString(psErrorCodeLast()));
-    // find or define a pmFPAfile PSPHOT.INPUT
-    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSPHOT.INPUT");
-    if (!status) {
-        psError(PSPHOT_ERR_CONFIG, false, "PSPHOT.INPUT I/O file is not defined");
-        return false;
-    }
-    printf("%x %s\n",psErrorCodeLast(),psErrorCodeString(psErrorCodeLast()));
-    // we make a new copy of the output chip to keep psphot from modifying the output image
-    pmChip *oldChip = pmFPAviewThisChip (view, input->src);
-    pmChip *newChip = pmFPAviewThisChip (view, input->fpa);
-    pmChipCopy (newChip, oldChip);
-    printf("%x %s\n",psErrorCodeLast(),psErrorCodeString(psErrorCodeLast()));
-    // iterate over the cells and readout for this chip
-    while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
-        psLogMsg ("ppImagePhotom", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-        if (! cell->process || ! cell->file_exists) { continue; }
-
-        // process each of the readouts
-        while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
-            if (! readout->data_exists) { continue; }
-	    printf("%x %s\n",psErrorCodeLast(),psErrorCodeString(psErrorCodeLast()));
-            // run the actual photometry analysis
-            if (!psphotReadout (config, view)) {
-                // This is likely a data quality issue
-                // XXX Split into multiple cases using error codes?
-                psErrorStackPrint(stderr, "Unable to perform photometry on image");
-                psWarning("Unable to perform photometry on image --- suspect bad data quality.");
-                if (stats && psMetadataLookupS32(NULL, stats, "QUALITY") == 0) {
-                    psMetadataAddS32(stats, PS_LIST_TAIL, "QUALITY", PS_META_REPLACE,
-                                     "Unable to perform photometry on image", psErrorCodeLast());
-                }
-                psErrorClear();
-                psphotFilesActivate(config, false);
-            }
-
-            // we want to save the MASK as modified by psphot, but not the data or weight
-            // free the old mask and replace with a memory copy of the new mask
-            pmReadout *oldReadout = pmFPAviewThisReadout(view, input->src);
-            pmReadout *newReadout = pmFPAviewThisReadout(view, input->fpa);
-            psFree (oldReadout->mask);
-            oldReadout->mask = psMemIncrRefCounter(newReadout->mask);
-        }
-    }
-
-    ppImageMemoryDump("photom");
-
-    // the PSPHOT.INPUT file is a temporary file used to carry PPIMAGE.CHIP to psphotReadout
-    // XXX not sure that this is needed...
-//    pmFPAfileActivate (config->files, false, "PSPHOT.INPUT");
-
-    return true;
-}
-
-// XXX do we need to deactivate all files and activate the psphot ones explicitly?
Index: anches/haf_branches/videophot2010/ppImage/src/ppImagePixelStats.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImagePixelStats.c	(revision 29946)
+++ 	(revision )
@@ -1,85 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-// calculate stats, including MD5
-bool ppImagePixelStats(pmConfig *config, psMetadata *stats, const ppImageOptions *options,
-                       const pmFPAview *inputView)
-{
-    bool mdok;              // Status of MD lookup
-
-    // loop over the cells/readouts for this chip
-    pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
-    *view = *inputView;
-
-    // perform the analysis of for this FPA
-    pmFPAfile *output = psMetadataLookupPtr(&mdok, config->files, "PPIMAGE.OUTPUT");
-    if (!output) {
-        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find output file (PPIMAGE.OUTPUT).");
-        psFree(view);
-        return false;
-    }
-
-    // select the corresponding chip
-    pmChip *chip = pmFPAviewThisChip(view, output->fpa);
-    if (!chip) {
-        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find requested chip.");
-        psFree(view);
-        return false;
-    }
-
-    // Perform statistics for this chip
-    if (options->doStats) {
-        if (!ppStatsPixels(stats, output->fpa, view, options->maskValue, config)) {
-            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate stats for image.");
-            psFree(view);
-            return false;
-        }
-
-        // extract the fringe amplitude from the analysis
-        if (options->doFringe && !ppStatsFringe(stats, chip, "FRINGE", "FRINGE.SOLUTION")) {
-            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to extract fringe solution for image.");
-            psFree(view);
-            return false;
-        }
-
-        // extract the fringe residual amplitude from the analysis
-        if (options->doFringe && !ppStatsFringe(stats, chip, "FRINGE_RESID", "FRINGE.RESIDUAL.SOLUTION")) {
-            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to extract fringe solution for image.");
-            psFree(view);
-            return false;
-        }
-    }
-
-
-    view->cell = view->readout = -1;
-    pmCell *cell = NULL;                // Cell from iteration
-    while ((cell = pmFPAviewNextCell(view, output->fpa, 1)) != NULL) {
-        if (!cell->process || !cell->file_exists) {
-            continue;
-        }
-
-        // Add MD5 information for cell
-        pmHDU *hdu = pmHDUFromCell(cell); // HDU that owns the cell
-        pmReadout *readout = NULL;      // Readout from iteration
-        while ((readout = pmFPAviewNextReadout(view, output->fpa, 1)) != NULL) {
-            const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
-            const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
-
-            psString headerName = NULL; // Header name for MD5
-            psStringAppend(&headerName, "MD5_%s_%s_%d", chipName, cellName, view->readout);
-
-            psVector *md5 = psImageMD5(readout->image); // md5 hash
-            psString md5string = psMD5toString(md5); // String
-            psFree(md5);
-            psMetadataAddStr(hdu->header, PS_LIST_TAIL, headerName, PS_META_REPLACE, "Image MD5", md5string);
-            psFree(md5string);
-            psFree(headerName);
-        }
-    }
-
-    psFree (view);
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageRebinReadout.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageRebinReadout.c	(revision 29946)
+++ 	(revision )
@@ -1,44 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageRebinChip (pmConfig *config, pmFPAview *view, ppImageOptions *options, char *outName) {
-
-    pmCell *cell;
-    pmReadout *inReadout, *outReadout;
-
-    pmFPAfile *outFile = psMetadataLookupPtr(NULL, config->files, outName);
-    if (outFile == NULL) return false;
-
-    // XXX double check that chip != -1?
-
-    pmChip *inChip  = pmFPAviewThisChip (view, outFile->src);
-    pmChip *outChip = pmFPAviewThisChip (view, outFile->fpa);
-    if (!pmChipCopyStructure (outChip, inChip, outFile->xBin, outFile->yBin)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to copy chip structure.");
-        return false;
-    }
-
-    while ((cell = pmFPAviewNextCell (view, outFile->src, 1)) != NULL) {
-        psLogMsg ("ppImageRebinChip", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-        if (! cell->process || ! cell->file_exists) { continue; }
-
-        // process each of the readouts
-        while ((inReadout = pmFPAviewNextReadout (view, outFile->src, 1)) != NULL) {
-            if (! inReadout->data_exists) { continue; }
-
-            outReadout = pmFPAviewThisReadout (view, outFile->fpa);
-
-            // run the rebin code
-            if (!pmReadoutRebin(outReadout, inReadout, options->maskValue, outFile->xBin, outFile->yBin)) {
-                psError(PS_ERR_UNKNOWN, false, "Unable to rebin readout.");
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
-
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageReplaceBackground.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageReplaceBackground.c	(revision 29946)
+++ 	(revision )
@@ -1,184 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-// In this function, we perform the psphot analysis routine for the chip-mosaicked images
-bool ppImageSubtractBackground(pmConfig *config, const pmFPAview *view, const ppImageOptions *options)
-{
-    psAssert(config, "Need configuration");
-    psAssert(view, "Need view to chip");
-    psAssert(options, "Need options");
-
-    if (!options->doBG) {
-        return true;
-    }
-
-    bool status;                        // Status of MD lookup
-    pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.CHIP"); // File to correct
-    if (!status) {
-        psError(PS_ERR_UNEXPECTED_NULL, true, "PPIMAGE.CHIP file is not defined");
-        return false;
-    }
-
-    psMetadata *ppImageRecipe = psMetadataLookupPtr(NULL, config->recipes, RECIPE_NAME);
-    psAssert(ppImageRecipe, "Need PPIMAGE recipe");
-    psMetadata *psphotRecipe = psMetadataLookupPtr(NULL, config->recipes, PSPHOT_RECIPE);
-    psAssert(psphotRecipe, "Need PSPHOT recipe");
-
-    // XXX Should this be options->maskValue or options->maskValue & ~options->satMask?
-    //     The latter will leave saturated pixels high
-    psImageMaskType maskVal = options->maskValue;
-
-    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
-    psMetadataAddImageMask(psphotRecipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask", maskVal);
-
-    // Since we are working on a chip-mosaicked image, there should only be a single cell and readout
-    pmChip *chip = pmFPAviewThisChip(view, input->fpa); // Chip of interest
-    if (!chip) {
-        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip");
-        return false;
-    }
-    if (chip->cells->n == 0) {
-        psWarning("Chip has no cells");
-        return true;
-    }
-    if (chip->cells->n > 1) {
-        psWarning("Chip has %ld cells; only the first will be processed", chip->cells->n);
-    }
-    pmCell *cell = chip->cells->data[0]; // Cell of interest
-    if (!cell || !cell->process || !cell->file_exists) {
-        // Nothing to process
-        return true;
-    }
-    if (cell->readouts->n == 0) {
-        psWarning("Cell has no readouts");
-        return true;
-    }
-    if (cell->readouts->n > 1) {
-        psWarning("Cell has %ld readouts; only the first will be processed", cell->readouts->n);
-    }
-    pmReadout *ro = cell->readouts->data[0]; // Readout of interest
-    if (!ro || !ro->data_exists) {
-        // Nothing to process
-        return true;
-    }
-    psImage *image = ro->image, *mask = ro->mask; // Image and mask of interest
-
-    // View corresponding to this readout
-    pmFPAview roView = *view;
-    roView.cell = roView.readout = 0;
-
-    // If the background model file has not been defined, psphotModelBackground will generate it
-    pmReadout *modelRO = NULL;
-    pmFPAfile *modelFile = psMetadataLookupPtr(&status, config->files, "PSPHOT.BACKMDL"); // Background model
-    if (modelFile && modelFile->fpa) {
-        modelRO = pmFPAviewThisReadout(&roView, modelFile->fpa); // Background model
-    }
-
-    // the background model has not been defined, or at least not generated
-    if (!modelFile || !modelRO) {
-        if (!psphotModelBackgroundReadoutFileIndex(config, &roView, "PPIMAGE.CHIP", 0)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to model background");
-            return false;
-        }
-        // the model file should now at least be defined
-        modelFile = psMetadataLookupPtr(&status, config->files, "PSPHOT.BACKMDL"); // Background model
-        if (!modelFile) {
-            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to define background model I/O file");
-            return false;
-        }
-        // now grab the readout from the correct location:
-        if (modelFile->mode == PM_FPA_MODE_INTERNAL) {
-            modelRO = modelFile->readout;
-        } else {
-            modelRO = pmFPAviewThisReadout(&roView, modelFile->fpa);
-        }
-        if (!modelRO) {
-            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find background model");
-            return false;
-        }
-    }
-    psImageBinning *binning = psMetadataLookupPtr(&status, modelRO->analysis,
-                                                  "PSPHOT.BACKGROUND.BINNING"); // Binning for model
-    if (!binning) {
-        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find background binning");
-        return false;
-    }
-
-# define USE_UNBIN 1
-# if (USE_UNBIN)
-    // select background pixels, from output background file, or create
-    pmReadout *background = NULL;
-    pmFPAfile *backfile = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKGND");
-    if (backfile) {
-        // we are using PSPHOT.BACKGND as an I/O file: select readout or create
-        if (backfile->mode == PM_FPA_MODE_INTERNAL) {
-            background = backfile->readout;
-        } else {
-            background = pmFPAviewThisReadout (&roView, backfile->fpa);
-        }
-        if (background == NULL) {
-            // readout does not yet exist: create from input
-            pmFPAfileCopyStructureView (backfile->fpa, input->fpa, 1, 1, &roView);
-            background = pmFPAviewThisReadout (&roView, backfile->fpa);
-            if ((image->numCols != background->image->numCols) || (image->numRows != background->image->numRows)) {
-                psError (PSPHOT_ERR_PROG, true, "inconsistent sizes for background dimensions");
-                return false;
-            }
-        }
-    } else {
-        background = pmFPAfileDefineInternal (config->files, "PSPHOT.BACKGND", image->numCols, image->numRows, PS_TYPE_F32);
-    }
-    psF32 **backData = background->image->data.F32;
-
-    // linear interpolation to full-scale
-    if (!psImageUnbin (background->image, modelRO->image, binning)) {
-        psError (PSPHOT_ERR_PROG, true, "inconsistent sizes for unbinning");
-        return false;
-    }
-
-    // Do the background subtraction
-    int numCols = image->numCols, numRows = image->numRows; // Size of image
-    for (int y = 0; y < numRows; y++) {
-        for (int x = 0; x < numCols; x++) {
-            if (mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) {
-                image->data.F32[y][x] = 0.0;
-            } else {
-		float value = backData[y][x];
-		if (!isfinite(value)) {
-		    image->data.F32[y][x] = NAN;
-		    mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= options->lowMask;
-		} else {
-		    image->data.F32[y][x] -= value;
-		}
-	    }
-        }
-    }
-# else
-    // Do the background subtraction
-    int numCols = image->numCols, numRows = image->numRows; // Size of image
-    for (int y = 0; y < numRows; y++) {
-        for (int x = 0; x < numCols; x++) {
-            if (mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) {
-                image->data.F32[y][x] = 0.0;
-            } else {
-                float value = psImageUnbinPixel(x + 0.5, y + 0.5, modelRO->image, binning); // Background value
-                if (!isfinite(value)) {
-                    image->data.F32[y][x] = NAN;
-                    mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= options->lowMask;
-                } else {
-                    image->data.F32[y][x] -= value;
-                }
-            }
-        }
-    }
-# endif
-
-    // XXX should these really be here?? (probably not...)
-    // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL");
-    // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL.STDEV");
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageSetMaskBits.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageSetMaskBits.c	(revision 29946)
+++ 	(revision )
@@ -1,60 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageSetMaskBits (pmConfig *config, ppImageOptions *options) {
-
-    if (!pmConfigMaskSetBits(&options->maskValue, &options->markValue, config)) {
-        psError (PS_ERR_UNKNOWN, true, "Unable to define the mask bit values");
-        return false;
-    }
-
-    // at this point we know we have valid values for required entries SAT, BAD, FLAT, BLANK:
-
-    // mask for bad flat corrections
-    options->flatMask = pmConfigMaskGet("FLAT", config);
-    psAssert (options->flatMask, "flat mask not set");
-
-    // mask for bad dark corrections
-    options->darkMask = pmConfigMaskGet("DARK", config);
-    psAssert (options->darkMask, "dark mask not set");
-
-    // mask for non-existent data  (default to DETECTOR if not defined)
-    options->blankMask = pmConfigMaskGet("BLANK", config);
-    psAssert (options->blankMask, "blank mask not set");
-
-    // mask for saturated data  (default to RANGE if not defined)
-    options->satMask = pmConfigMaskGet("SAT", config);
-    psAssert (options->satMask, "sat mask not set");
-
-    // mask for below-range data  (default to RANGE if not defined)
-    options->lowMask = pmConfigMaskGet("LOW", config);
-    if (!options->lowMask) {
-        // look up old name for backward compatability
-        options->lowMask = pmConfigMaskGet("BAD", config);
-    }
-    psAssert (options->lowMask, "low mask not set");
-
-    // mask for suspect regions due to burntool if we need to.
-    if (options->doMaskBurntool) {
-      options->burntoolMask = pmConfigMaskGet("BURNTOOL",config);
-      psAssert (options->burntoolMask, "burntool mask not set");
-    }
-    
-    // save MASK and MARK on the PSPHOT recipe
-    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
-    if (!recipe) {
-        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);
-        return false;
-    }
-
-    // set maskValue and markValue in the psphot recipe
-    psMetadataAddImageMask(recipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask",
-                           options->maskValue);
-    psMetadataAddImageMask(recipe, PS_LIST_TAIL, "MARK.PSPHOT", PS_META_REPLACE, "user-defined mask",
-                           options->markValue);
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageSetThreads.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageSetThreads.c	(revision 29946)
+++ 	(revision )
@@ -1,26 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-bool ppImageThread_ppImageDetrendReadout (psThreadJob *job) {
-
-    pmConfig *config        = job->args->data[0];
-    ppImageOptions *options = job->args->data[1];
-    pmFPAview *view         = job->args->data[2];
-
-    bool status = ppImageDetrendReadout(config, options, view);
-    return status;
-}
-
-bool ppImageSetThreads () {
-
-    psThreadTask *task = NULL;
-
-    task = psThreadTaskAlloc ("PPIMAGE_DETREND_READOUT", 3);
-    task->function = &ppImageThread_ppImageDetrendReadout;
-    psThreadTaskAdd (task);
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageStatsOutput.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageStatsOutput.c	(revision 29946)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-
-// write stats to output file
-bool ppImageStatsOutput(pmConfig *config, psMetadata *stats, const ppImageOptions *options)
-{
-    bool mdok;
-
-    // measure statistics, or ignore?
-    if (!options->doStats) {
-        return true;
-    }
-
-    // get the output stats filename
-    const char *statsName = psMetadataLookupStr(&mdok, config->arguments, "STATS"); // Filename for statistics
-    if (!statsName || !strlen(statsName)) {
-        psError(PS_ERR_UNEXPECTED_NULL, false, "missing STATS entry in arguments list.");
-        return false;
-    }
-
-    // Write out
-    psString resolved = pmConfigConvertFilename(statsName, config, true, true); // Resolved filename
-    if (!resolved) {
-        psError(psErrorCodeLast(), false, "Unable to resolve statistics file name");
-        return false;
-    }
-    if (!psMetadataConfigWrite(stats, resolved)) {
-        psError(psErrorCodeLast(), false, "Unable to serialize stats metadata.\n");
-        psFree(resolved);
-        return false;
-    }
-    psFree(resolved);
-
-    pmConfigRunFilenameAddWrite(config, "STATS", statsName);
-
-    return true;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageVersion.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageVersion.c	(revision 29946)
+++ 	(revision )
@@ -1,115 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ppImage.h"
-#include "ppImageVersionDefinitions.h"
-
-#ifndef PPIMAGE_VERSION
-#error "PPIMAGE_VERSION is not set"
-#endif
-#ifndef PPIMAGE_BRANCH
-#error "PPIMAGE_BRANCH is not set"
-#endif
-#ifndef PPIMAGE_SOURCE
-#error "PPIMAGE_SOURCE is not set"
-#endif
-
-psString ppImageVersion(void)
-{
-    char *value = NULL;
-    psStringAppend(&value, "%s@%s", PPIMAGE_BRANCH, PPIMAGE_VERSION);
-    return value;
-}
-
-psString ppImageSource(void)
-{
-    return psStringCopy(PPIMAGE_SOURCE);
-}
-
-psString ppImageVersionLong(void)
-{
-    psString version = ppImageVersion();  // Version, to return
-    psString source = ppImageSource(); // Source
-
-    psStringPrepend(&version, "ppImage ");
-    psStringAppend(&version, " from %s, built %s, %s", source, __DATE__, __TIME__);
-    psFree(source);
-
-#ifdef __OPTIMIZE__
-    psStringAppend(&version, " optimised");
-#else
-    psStringAppend(&version, " unoptimised");
-#endif
-
-    return version;
-};
-
-bool ppImageVersionHeader(psMetadata *header)
-{
-    PS_ASSERT_METADATA_NON_NULL(header, false);
-
-    psTime *time = psTimeGetNow(PS_TIME_TAI); // The time now
-    psString timeString = psTimeToISO(time); // The time in an ISO string
-    psFree(time);
-    psString history = NULL;               // History string
-    psStringAppend(&history, "ppImage at %s", timeString);
-    psFree(timeString);
-    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, history);
-    psFree(history);
-
-    psLibVersionHeader(header);
-    psModulesVersionHeader(header);
-    psphotVersionHeader(header);
-    psastroVersionHeader(header);
-    ppStatsVersionHeader(header);
-
-    psString version = ppImageVersion(); // ppImage software version
-    psString source  = ppImageSource();  // ppImage software source
-
-    psMetadataAddStr(header, PS_LIST_TAIL, "IMAGE_V", PS_META_REPLACE, NULL, PPIMAGE_VERSION);
-    
-    psStringPrepend(&version, "ppImage version: ");
-    psStringPrepend(&source, "ppImage source: ");
-
-    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, version);
-    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, source);
-
-    psFree(version);
-    psFree(source);
-
-    return true;
-}
-
-
-void ppImageVersionPrint(void)
-{
-    psTime *time = psTimeGetNow(PS_TIME_TAI); // The time now
-    psString timeString = psTimeToISO(time); // The time in an ISO string
-    psFree(time);
-    psLogMsg("ppImage", PS_LOG_INFO, "ppImage at %s", timeString);
-    psFree(timeString);
-
-    psString pslib = psLibVersionLong();// psLib version
-    psString psmodules = psModulesVersionLong(); // psModules version
-    psString psphot = psphotVersionLong(); // psphot version
-    psString psastro = psastroVersionLong(); // psastro version
-    psString ppStats = ppStatsVersionLong(); // ppStats version
-    psString ppImage = ppImageVersionLong(); // ppImage version
-
-    psLogMsg("ppImage", PS_LOG_INFO, "%s", pslib);
-    psLogMsg("ppImage", PS_LOG_INFO, "%s", psmodules);
-    psLogMsg("ppImage", PS_LOG_INFO, "%s", psphot);
-    psLogMsg("ppImage", PS_LOG_INFO, "%s", psastro);
-    psLogMsg("ppImage", PS_LOG_INFO, "%s", ppStats);
-    psLogMsg("ppImage", PS_LOG_INFO, "%s", ppImage);
-
-    psFree(pslib);
-    psFree(psmodules);
-    psFree(psphot);
-    psFree(psastro);
-    psFree(ppStats);
-    psFree(ppImage);
-
-    return;
-}
Index: anches/haf_branches/videophot2010/ppImage/src/ppImageVersionDefinitions.h.in
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/ppImageVersionDefinitions.h.in	(revision 29946)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#ifndef PPIMAGE_VERSION_DEFINITIONS_H
-#define PPIMAGE_VERSION_DEFINITIONS_H
-
-#define PPIMAGE_VERSION @PPIMAGE_VERSION@ // SVN version
-#define PPIMAGE_BRANCH  @PPIMAGE_BRANCH@  // SVN branch
-#define PPIMAGE_SOURCE  @PPIMAGE_SOURCE@  // SVN source
-
-#endif
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideoLoop.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideoLoop.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideoLoop.c	(revision 29947)
@@ -0,0 +1,141 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "psvideophot.h"
+
+#define ESCAPE(MESSAGE) { \
+  psError(PS_ERR_UNKNOWN, false, MESSAGE); \
+  psFree(view); \
+  pmFPAfileFreeSetStrict(false); \
+  return false; \
+}
+
+bool psvideophotLoop(pmConfig *config, psvideophotOptions *options)
+{
+    psMetadata *stats = NULL;           // Statistics to output
+    float timeDetrend = 0;              // Amount of time spent in detrend
+    float timePhot = 0;                 // Amount of time spent in photometry
+
+    if (options->doStats) {
+        stats = psMetadataAlloc();
+        psMetadataAddS32(stats, PS_LIST_TAIL, "QUALITY", 0, "No problems", 0);
+    }
+
+    bool status;                        // Status of MD lookup
+
+    pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PSVIDEOPHOT.INPUT");
+    
+    if (!status) {
+        psErrorStackPrint(stderr, "Can't find input data!\n");
+        psvideophotCleanup(config, options);
+        exit(PS_EXIT_PROG_ERROR);
+    }
+
+    pmConfigCamerasCull(config, NULL);
+    pmConfigRecipesCull(config, "PSVIDEOPHOT,PPSTATS,PSPHOT,MASKS,PSASTRO,JPEG");
+
+    pmFPAview *view = pmFPAviewAlloc(0);// View for level of interest
+    pmHDU *lastHDU = NULL;              // Last HDU that was updated
+
+    // files associated with the science image
+    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+        ESCAPE("load failure for FPA");
+    }
+
+    pmChip *chip;                       // Chip from FPA
+    while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) {
+        psLogMsg ("psvideophotLoop", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process || !chip->file_exists) {
+            continue;
+        }
+        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+            ESCAPE("load failure for Chip");
+        }
+
+
+        psTimerStart(TIMER_DETREND);
+        pmCell *cell;                   // Cell from chip
+        while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
+            psLogMsg ("psvideophotLoop", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+            if (!cell->process || !cell->file_exists) {
+                continue;
+            }
+            if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+                ESCAPE("load failure for Cell");
+            }
+
+            // Put version information into the header
+            pmHDU *hdu = pmHDUGetHighest(input->fpa, chip, cell);
+            if (hdu && hdu != lastHDU) {
+                psvideophotVersionHeader(hdu->header);
+                lastHDU = hdu;
+            }
+
+            // XXX for now, skip the video cells (cell->readouts->n > 1)
+            if (cell->readouts->n <2) {
+	      psWarning("Skipping Non-Video Cell for psvideophotDetrendReadout");
+	      continue; 
+	    }
+
+            // process each of the readouts
+            pmReadout *readout;         // Readout from cell
+            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
+	      if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
+                    ESCAPE("load failure for Readout");
+	      }
+                if (!readout->data_exists) {
+                    continue;
+                }
+
+            }
+	    
+	    
+
+        }
+        // free detrend images potentially in use: MASK, BIAS, DARK, SHUTTER, FLAT
+        timeDetrend += psTimerClear(TIMER_DETREND);
+
+        // we perform photometry on the readouts of this chip in the output
+
+        psTimerStart(TIMER_PHOT);
+        timePhot += psTimerClear(TIMER_PHOT);
+
+        view->cell = -1;
+        while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
+            if (!cell->process || !cell->file_exists) {
+                continue;
+            }
+            if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+                ESCAPE("save failure for Cell");
+            }
+        }
+
+        // Close chip
+        if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+            ESCAPE("save failure for Chip");
+        }
+    }
+    
+    if (psTraceGetLevel("psvideophot") >= 3) {
+        psvideophotFileCheck(config);
+    }
+    
+    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
+        ESCAPE("save failure for FPA");
+    }
+    psFree(view);
+
+    // Dump configuration
+    psString dump_file = psMetadataLookupStr(&status, config->arguments, "DUMP_CONFIG");
+    if (dump_file) {
+        if (!pmConfigDump(config, dump_file)) {
+            ESCAPE("Unable to dump configuration.");
+        }
+    }
+
+
+    psFree (stats);
+
+    return true;
+}
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophot.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophot.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophot.c	(revision 29947)
@@ -0,0 +1,48 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "psvideophot.h"
+
+int main(int argc, char **argv) {
+
+    psLibInit(NULL);
+
+    psTimerStart(TIMER_TOTAL);
+
+    // Parse the configuration and arguments
+    // Open the input image(s)
+    // Determine camera, format from header if not already defined
+    // Construct camera in preparation for reading
+    pmConfig *config = psvideophotArguments(argc, argv);
+    if (config == NULL) {
+        psErrorStackPrint(stderr, "Unable to parse command-line arguments.");
+        psvideophotCleanup(config, NULL);
+        exit(PS_EXIT_CONFIG_ERROR);
+    }
+
+    psvideophotVersionPrint();
+
+    // define recipe options
+    // define the active I/O files
+     psvideophotOptions *options = psvideophotParseCamera(config);
+    if (options == NULL) {
+        psErrorStackPrint(stderr, "Unable to parse camera.");
+        psvideophotCleanup(config, options);
+        exit(PS_EXIT_CONFIG_ERROR);
+    }
+
+    // Image Arithmetic Loop
+    if (!psvideophotLoop(config, options)) {
+        psErrorStackPrint(stderr, "Unable to loop over input");
+        psvideophotCleanup(config, options);
+        exit(PS_EXIT_SYS_ERROR);
+    }
+
+    psLogMsg("psvideophot", PS_LOG_INFO, "Complete psvideophot run: %f sec\n", psTimerMark(TIMER_TOTAL));
+
+    // Cleaning up
+    //    psvideophotCleanup(config, options);
+
+    return PS_EXIT_SUCCESS;
+}
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophot.h
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophot.h	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophot.h	(revision 29947)
@@ -0,0 +1,293 @@
+#ifndef PS_VIDEOPHOT_H
+#define PS_VIDEOPHOT_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>  // for strcasecmp
+#include <unistd.h>   // for unlink
+#include "pslib.h"
+#include "psmodules.h"
+#include "psphot.h"
+#include "psastro.h"
+#include "ppStats.h"
+
+#define RECIPE_NAME "PSVIDEOPHOT"           // Name of the recipe to use
+#define TIMER_TOTAL   "PSVIDEOPHOT.TOTAL"   // Name of timer for total time
+#define TIMER_DETREND "PSVIDEOPHOT.DETREND" // Name of timer for detrend time
+#define TIMER_PHOT    "PSVIDEOPHOT.PHOT"    // Name of timer for photometry time
+
+// Options for psvideophot processing
+typedef struct {
+    // actions which psvideophot should perform
+    bool doMaskBuild;                   // Build internal mask
+    bool doVarianceBuild;               // Build internal variance map
+    bool doMaskBurntool;                // mask potential burntool trails
+    bool doMaskSat;                     // mask saturated pixels
+    bool doMaskLow;                     // mask low pixels
+    bool doMask;                        // Mask bad pixels
+    bool doNonLin;                      // Non-linearity correction
+    bool doOverscan;                    // Overscan subtraction
+    bool doNoiseMap;                    // Bias subtraction
+    bool doBias;                        // Bias subtraction
+    bool doDark;                        // Dark subtraction
+    bool doRemnance;                    // Remnance masking
+    bool doShutter;                     // Shutter correction
+    bool doFlat;                        // Flat-field normalisation
+    bool doPatternRow;                  // Row pattern correction
+    bool doPatternCell;                 // Cell pattern correction
+    bool doFringe;                      // Fringe subtraction
+    bool doPhotom;                      // Source identification and photometry
+    bool doBG;                          // Background subtraction
+    bool doAstromChip;                  // per-chip Astrometry
+    bool doAstromMosaic;                // full-mosaic Astrometry
+    bool doStats;                       // call ppStats on the image
+    bool checkCTE;                      // measure pixel-based variance
+    bool applyParity;                   // Apply Cell parities
+
+  bool doMaskStats;                      // Calculate mask statistics
+  
+    bool doCrosstalkMeasure;            // measure crosstalk signal
+    bool doCrosstalkCorrect;            // apply crosstalk correction
+
+    // output files requested
+    bool BaseFITS;
+    bool BaseMaskFITS;
+    bool BaseVarianceFITS;
+
+    bool ChipFITS;
+    bool ChipMaskFITS;
+    bool ChipVarianceFITS;
+
+    bool FPA1FITS;
+    bool FPA2FITS;
+    bool Bin1FITS;
+    bool Bin1JPEG;
+    bool Bin2FITS;
+    bool Bin2JPEG;
+
+    // make values for abstract concepts of masking
+    psImageMaskType maskValue;          // apply this bit-mask to choose masked bits
+    psImageMaskType markValue;          // apply this bit-mask to choose masked bits
+    psImageMaskType satMask;            // Mask value to give saturated pixels
+    psImageMaskType lowMask;            // Mask value to give bad pixels
+    psImageMaskType flatMask;           // Mask value to give bad flat pixels
+    psImageMaskType darkMask;           // Mask value to give bad dark pixels
+    psImageMaskType blankMask;          // Mask value to give blank pixels
+    psImageMaskType burntoolMask;       // Suspect pixels that fall where a burntool trail is expected.
+    // non-linear correction parameters
+    psDataType nonLinearType;
+    psMetadataItem *nonLinearData;
+    void *nonLinearSource;
+
+    // options for the analysis
+    pmOverscanOptions *overscan;        // Overscan options
+    int burntoolTrails;
+    // binning parameters
+    int xBin1;                          // x-binning, scale 1
+    int yBin1;                          // y-binning, scale 1
+    int xBin2;                          // x-binning, scale 2
+    int yBin2;                          // y-binning, scale 2
+
+    // parameters used by the fringe analysis
+    float fringeRej;                    // Fringe rejection limit
+    int fringeIter;                     // Fringe iterations
+    float fringeKeep;                   // Fringe keep fraction
+
+    // Pattern correction
+    int patternRowOrder;                   // Polynomial order
+    int patternRowIter;                    // Clipping iterations
+    float patternRowRej;                   // Clipping threshold
+    float patternRowThresh;                // Ignore threshold
+    psStatsOptions patternRowMean;         // Statistic for mean
+    psStatsOptions patternRowStdev;        // Statistic for stdev
+    psStatsOptions patternCellBG;          // statistic for background
+    psStatsOptions patternCellMean;        // Statistic for mean
+
+    int remnanceSize;                   // Size for remnance detection
+    float remnanceThresh;               // Threshold for remnance detection
+
+    char *normClass;                    // class to use for per-class normalization
+
+  psU16 maskstat_static;
+  psU16 maskstat_dynamic;
+  psU16 maskstat_magic;
+  psU16 maskstat_advisory;
+  
+} psvideophotOptions;
+
+// Cells to be used in the detrend
+typedef struct {
+    pmCell *input;                      // The input cell, to be operated upon
+    pmCell *mask;                       // The bad pixel mask
+    pmCell *bias;                       // The bias correction
+    pmCell *dark;                       // The dark correction
+    pmCell *flat;                       // The flat-field correction
+} psvideophotDetrend;
+
+psvideophotOptions *psvideophotOptionsAlloc(void);
+
+// Determine the processing options
+psvideophotOptions *psvideophotOptionsParse(pmConfig *config);
+
+// Get the configuration
+pmConfig *psvideophotArguments(int argc, char **argv);
+
+// Determine what type of camera, and initialise
+psvideophotOptions *psvideophotParseCamera(pmConfig *config);
+bool psvideophotSetMaskBits (pmConfig *config, psvideophotOptions *options);
+
+// apply the cell flips to the input data before analysis
+bool psvideophotParityFlip (pmConfig *config, const psvideophotOptions *options, const pmFPAview *view, bool native);
+
+// Loop over the input
+bool psvideophotLoop(pmConfig *config, psvideophotOptions *options);
+
+// free memory, check for leaks
+void psvideophotCleanup (pmConfig *config, psvideophotOptions *options);
+
+// perform the detrend analysis on the current readout
+bool psvideophotDetrendReadout (pmConfig *config, psvideophotOptions *options, pmFPAview *view);
+
+bool psvideophotDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, psvideophotOptions *options);
+
+//bool psvideophotDetrendNonLinear(pmReadout *input, psvideophotOptions *options);
+bool psvideophotDetrendNonLinear(pmReadout *input, pmFPAview *linearity, pmConfig *config);
+bool psvideophotDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem);
+bool psvideophotDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem);
+
+bool psvideophotDetrendCell(psvideophotDetrend *detrend, psvideophotOptions *options, pmConfig *config);
+bool psvideophotDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, psvideophotOptions *options);
+pmReadout* psvideophotDetrendSelectFirst(pmCell *cell, char *name, bool doThis);
+
+bool psvideophotDetrendFree(pmConfig *config, pmFPAview *view);
+bool psvideophotFringeFree(pmConfig *config, pmFPAview *view);
+
+bool psvideophotCheckCTE(pmConfig *config, psvideophotOptions *options, pmFPAview *view);
+
+bool psvideophotBurntoolMask(pmConfig *config, psvideophotOptions *options, pmFPAview *view, pmReadout *mask);
+
+bool psvideophotDetrendPatternApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, const psvideophotOptions *options);
+
+// Record which detrend file was used for the detrending
+bool psvideophotDetrendRecord(
+    pmCell *cell,                       // Cell of interest
+    const pmConfig *config,             // Configuration
+    const psvideophotOptions *options,      // Processing options
+    const pmFPAview *view               // View to cell
+    );
+
+bool psvideophotRebinChip (pmConfig *config, pmFPAview *view, psvideophotOptions *options, char *outName);
+
+bool psvideophotPhotom(psMetadata *stats, pmConfig *config, pmFPAview *view);
+bool psvideophotAstrom(pmConfig *config, psMetadata *stats);
+bool psvideophotAddstar(pmConfig *config);
+
+// Subtract background from the chip-mosaicked image
+bool psvideophotSubtractBackground(
+    pmConfig *config,                   // Configuration
+    const pmFPAview *view,              // View to chip of interest
+    const psvideophotOptions *options       // Processing options
+    );
+
+bool psvideophotMosaicChip (pmConfig *config, const psvideophotOptions *options, const pmFPAview *view,
+                        const char *outFile, const char *inFile);
+bool psvideophotMosaicFPA (pmConfig *config, const psvideophotOptions *options,
+                       const char *outFile, const char *inFile);
+
+bool psvideophotSetMaskBits (pmConfig *config, psvideophotOptions *options);
+
+void psvideophotFileCheck (pmConfig *config);
+
+// functions used by ppFocus
+pmConfig *ppFocusArguments(int argc, char **argv);
+psvideophotOptions *ppFocusParseCamera (pmConfig *config, int entry);
+bool ppFocusGetFWHM (pmConfig *config, psVector *focus, psVector *fwhm);
+bool ppFocusFitFWHM (pmConfig *config, psVector *focus, psVector *fwhm);
+
+void ppFocusDropCamera (pmConfig *config);
+
+bool psvideophotDefineFile (pmConfig *config, pmFPA *input, char *filerule, char *argname, pmFPAfileType fileType, pmDetrendType detrendType);
+
+// write stats to output file
+bool psvideophotStatsOutput(pmConfig *config, // Configuration
+                        psMetadata *stats, // Statistics output
+                        const psvideophotOptions *options // Options
+    );
+
+
+// measure the crosstalk signal
+bool psvideophotMeasureCrosstalk(pmConfig *config, psvideophotOptions *options, pmFPAview *view);
+
+// correct the crosstalk signal
+bool psvideophotCorrectCrosstalk(pmConfig *config, psvideophotOptions *options, pmFPAview *view);
+
+// Measure fringes
+bool psvideophotDetrendFringeMeasure(pmReadout *readout, // Readout to measure
+                                 pmCell *fringe, // Fringe cell (each readout is a different component)
+                                 const bool isResidual,
+                                 const psvideophotOptions *options // Options
+    );
+
+// Solve the fringe system
+bool psvideophotDetrendFringeSolve(pmChip *scienceChip, // Chip with science
+                               const pmChip *refChip, // Chip with reference fringes
+                               const bool isResidual,
+                               const psvideophotOptions *options // Options
+    );
+
+// Generate fringe frame
+bool psvideophotDetrendFringeGenerate(pmCell *science, // Science cell
+                                  pmCell *fringes, // Fringe cell, one readout per fringe component
+                                  const psvideophotOptions *options // Options
+    );
+
+
+bool psvideophotDetrendFringeApply (pmConfig *config, // config
+                                pmChip *chip, // science chip
+                                const pmFPAview *inputView, // current view
+                                const psvideophotOptions *options // options
+    );
+
+/// Return short version information
+psString psvideophotVersion(void);
+
+/// Return software source
+psString psvideophotSource(void);
+
+/// Return long version information
+psString psvideophotVersionLong(void);
+
+/// Populate the header with version information for all dependencies
+bool psvideophotVersionHeader(psMetadata *metadata ///< Header to populate
+    );
+
+/// Print version information
+void psvideophotVersionPrint(void);
+
+
+// calculate stats, including MD5
+bool psvideophotPixelStats(pmConfig *config,// Configuration
+                       psMetadata *stats, // Statistics output
+                       const psvideophotOptions *options, // Options
+                       const pmFPAview *inputView // View to data
+    );
+
+// Calculate Mask statistics
+bool psvideophotMaskStats(pmConfig *config, pmFPAview *view, psMetadata *stats);
+
+// calculate stats from headers and concepts
+bool psvideophotMetadataStats(pmConfig *config, // Configuration
+                          psMetadata *stats, // Statistics output
+                          const psvideophotOptions *options // Options
+    );
+
+void psvideophotFileCheck(pmConfig *config);
+
+/// Dump memory summary to text file
+void psvideophotMemoryDump(const char *description);
+
+#endif
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotArguments.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotArguments.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotArguments.c	(revision 29947)
@@ -0,0 +1,173 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "psvideophot.h"
+
+static void usage (void) {
+    fprintf(stderr, "USAGE: psvideophot [-file INPUT.fits] [-list INPUT.txt] OUTPUT\n\n");
+    fprintf(stderr, "Optional arguments:\n");
+    fprintf(stderr, "\t-stats STATS.mdc: Output statistics into STATS.mdc\n");
+    fprintf(stderr, "\t-isfringe: The input image contains fringe data.\n");
+    fprintf(stderr, "\t-isdark: The input image contains dark data.\n");
+    fprintf(stderr, "\t-usemask MASKVAL: Use this mask value (override recipe).\n");
+    fprintf(stderr, "\t-chip CHIPNUM: Only process this chip number.\n");
+    fprintf(stderr, "\t-norm VALUE: Divide through by this value when done.\n");
+    fprintf(stderr, "\t-normlist file.mdc: normalizations by class_id.\n");
+    fprintf(stderr, "\t-video: process video cells\n");
+    fprintf(stderr, "\n");
+    fprintf(stderr, "Input options (single file / file list):\n");
+    fprintf(stderr, "\t-noisemap/-noisemaplist: Noise Map image.\n");
+    fprintf(stderr, "\t-bias/-biaslist: Bias image.\n");
+    fprintf(stderr, "\t-dark/-darklist: Dark image.\n");
+    fprintf(stderr, "\t-shutter/-shutterlist: Shutter image.\n");
+    fprintf(stderr, "\t-flat/-flatlist: Flat image.\n");
+    fprintf(stderr, "\t-mask/-masklist: Mask image.\n");
+    fprintf(stderr, "\t-fringe/-fringelist: Fringe image and data.\n");
+    fprintf(stderr, "\t-linearity/-linearlist: linearity correction file.\n");
+    fprintf(stderr, "\n");
+    exit (2);
+}
+
+pmConfig *psvideophotArguments(int argc, char **argv)
+{
+    int argnum;                         // Argument number of interest
+
+    if (argc == 1) {
+        usage();
+    }
+
+    if (psArgumentGet (argc, argv, "-version")) {
+        psString version;
+        version = psvideophotVersionLong();   fprintf (stdout, "%s\n", version); psFree (version);
+        version = ppStatsVersionLong();   fprintf (stdout, "%s\n", version); psFree (version);
+        version = psphotVersionLong();    fprintf (stdout, "%s\n", version); psFree (version);
+        version = psastroVersionLong();   fprintf (stdout, "%s\n", version); psFree (version);
+        version = psModulesVersionLong(); fprintf (stdout, "%s\n", version); psFree (version);
+        version = psLibVersionLong();     fprintf (stdout, "%s\n", version); psFree (version);
+        exit (0);
+    }
+
+    // load the site-wide configuration information
+    pmConfig *config = pmConfigRead(&argc, argv, RECIPE_NAME);
+    if (config == NULL) {
+        psErrorStackPrint(stderr, "Can't find site configuration!\n");
+        exit(EXIT_FAILURE);
+    }
+
+    // save the following additional recipe values based on command-line options
+    // these options override the PSVIDEOPHOT recipe values loaded from recipe files
+    psMetadata *options = pmConfigRecipeOptions (config, RECIPE_NAME);
+
+    // save these recipe options until we have loaded the options
+    // psMetadata *options = psMetadataAlloc ();
+    // psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "PSVIDEOPHOT.OPTIONS",  PS_DATA_METADATA, "", options);
+
+    if ((argnum = psArgumentGet(argc, argv, "-stats"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "STATS", PS_META_REPLACE,
+                         "Filename for summary statistics", argv[argnum]);
+        psArgumentRemove(argnum, &argc, argv);
+    }
+
+    if ((argnum = psArgumentGet(argc, argv, "-isfringe"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "INPUT_IS_FRINGE", PS_META_REPLACE,
+                          "Input is fringe image", true);
+    }
+    if ((argnum = psArgumentGet(argc, argv, "-isdark"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "INPUT_IS_DARK", PS_META_REPLACE,
+                          "Input is dark image", true);
+    }
+    
+    if ((argnum = psArgumentGet(argc, argv, "-video"))) {
+      psArgumentRemove(argnum, &argc, argv);
+      psMetadataAddBool(config->arguments, PS_LIST_TAIL, "PROCESS_VIDEO", PS_META_REPLACE, "process video cells", true);
+    }
+
+    if ((argnum = psArgumentGet(argc, argv, "-visual"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        pmVisualSetVisual(true);
+    }
+
+    // Number of threads
+    if ((argnum = psArgumentGet(argc, argv, "-threads"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        int nThreads = atoi(argv[argnum]);
+        psMetadataAddS32(config->arguments, PS_LIST_TAIL, "NTHREADS", 0, "number of warp threads", nThreads);
+        psArgumentRemove(argnum, &argc, argv);
+
+        // create the thread pool with number of desired threads, supplying our thread launcher function
+        // XXX need to determine the number of threads from the config data
+        psThreadPoolInit (nThreads);
+    }
+
+    // the following options override the PSVIDEOPHOT recipe options
+
+    // recipe option: -usemask : override MASK setting in recipe
+    if ((argnum = psArgumentGet(argc, argv, "-usemask"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        psMetadataAddBool(options, PS_LIST_TAIL, "MASK", PS_META_REPLACE, "", true);
+        psArgumentRemove(argnum, &argc, argv);
+    }
+
+    // XXX add other PSVIDEOPHOT recipe options here
+
+    // the input file is a required argument; if not found, we will exit
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "INPUT", "-file", "-list");
+
+    // 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, "NOISEMAP", "-noisemap", "-noisemaplist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "BIAS", "-bias", "-biaslist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "DARK", "-dark", "-darklist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "SHUTTER", "-shutter", "-shutterlist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "FLAT", "-flat", "-flatlist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "MASK", "-mask", "-masklist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "FRINGE", "-fringe", "-fringelist");
+    pmConfigFileSetsMD (config->arguments, &argc, argv, "LINEARITY", "-linearity", "-linearlist");
+
+    // chip selection is used to limit chips to be processed
+    if ((argnum = psArgumentGet (argc, argv, "-chip"))) {
+        psArgumentRemove (argnum, &argc, argv);
+        psMetadataAddStr (config->arguments, PS_LIST_TAIL, "CHIP_SELECTIONS", PS_DATA_STRING, "", argv[argnum]);
+        psArgumentRemove (argnum, &argc, argv);
+    }
+
+    // Optional normalization factor
+    if ((argnum = psArgumentGet(argc, argv, "-norm"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        float norm = atof(argv[argnum]);
+        psMetadataAddF32(config->arguments, PS_LIST_TAIL, "NORMALIZATION", 0,
+                         "Normalisation to apply", norm);
+        psArgumentRemove(argnum, &argc, argv);
+    }
+
+    // Optional per-class normalization table
+    if ((argnum = psArgumentGet(argc, argv, "-normlist"))) {
+        psArgumentRemove(argnum, &argc, argv);
+
+        unsigned int nFail = 0;
+        psMetadata *normlist = psMetadataConfigRead (NULL, &nFail, argv[argnum], false);
+        // XXX allow this file to be in nebulous?
+
+        psMetadataAddMetadata(config->arguments, PS_LIST_TAIL, "NORMALIZATION.TABLE", 0, "Normalization to apply", normlist);
+        psFree (normlist);
+        psArgumentRemove(argnum, &argc, argv);
+    }
+
+    if ((argnum = psArgumentGet(argc, argv, "-dumpconfig"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "DUMP_CONFIG", PS_META_REPLACE,
+                         "Filename for configuration dump", argv[argnum]);
+        psArgumentRemove(argnum, &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: /branches/haf_branches/videophot2010/ppImage/src/psvideophotCleanup.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotCleanup.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotCleanup.c	(revision 29947)
@@ -0,0 +1,35 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+# include "psvideophot.h"
+
+void psvideophotCleanup (pmConfig *config, psvideophotOptions *options)
+{
+    if (psErrorCodeLast() != PS_ERR_NONE) {
+        pmFPAfileFreeSetStrict(false);
+    }
+
+    // Free memory used by psvideophot
+    psFree(options);
+    psFree(config);
+
+    // Free memory used by psModules
+    pmSourceFitSetDone ();
+    pmConceptsDone();
+    pmConfigDone();
+    pmModelClassCleanup();
+    pmVisualCleanup ();
+
+    // Free memory used by psLib
+    psLibFinalize();
+
+    // psMemBlock **memblocks;
+    // int Nleaks = psMemCheckLeaks (0, &memblocks, stderr, false);
+    // fprintf (stderr, "Found %d leaks at %s\n", Nleaks, "psvideophot");
+
+    // fprintf(stderr, "Found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "psvideophot");
+    psLogMsg("psvideophot", PS_LOG_INFO, "Memory leaks: %d\n", psMemCheckLeaks(0, NULL, stdout, false));
+
+    return;
+}
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotDefineFile.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotDefineFile.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotDefineFile.c	(revision 29947)
@@ -0,0 +1,56 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+# include "psvideophot.h"
+
+bool psvideophotDefineFile(pmConfig *config, pmFPA *input, char *filerule, char *argname,
+                       pmFPAfileType fileType, pmDetrendType detrendType)
+{
+    bool status;
+    pmFPAfile *file = NULL;             // File to be defined
+
+    if (!file) {
+        // look for the file on the argument list
+        file = pmFPAfileDefineFromArgs(&status, config, filerule, argname);
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition ARG LIST");
+            return false;
+        }
+    }
+    if (!file) {
+        // look for the file on the RUN metadata
+        file = pmFPAfileDefineFromRun(&status, NULL, config, filerule);
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition RUN");
+            return false;
+        }
+    }
+    if (!file) {
+        // look for the file in the camera config table
+        file = pmFPAfileDefineFromConf(&status, config, filerule);
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition CONFIG");
+            return false;
+        }
+    }
+    if (!file) {
+        // look for the file to be loaded from the detrend database
+        file = pmFPAfileDefineFromDetDB(&status, config, filerule, input, detrendType);
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to load file definition DETREND");
+            return false;
+        }
+    }
+
+    if (!file) {
+        return false;
+    }
+
+    if (file->type != fileType) {
+        psError(PS_ERR_IO, true, "%s is not of type %s", filerule, pmFPAfileStringFromType(fileType));
+        return false;
+    }
+    return true;
+}
+
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotFileCheck.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotFileCheck.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotFileCheck.c	(revision 29947)
@@ -0,0 +1,60 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "psvideophot.h"
+
+void psvideophotFileCheck (pmConfig *config) {
+
+    // add the output names to the output-type files
+    psMetadataItem *item = NULL;
+    psMetadataIterator *iter = psMetadataIteratorAlloc (config->files, PS_LIST_HEAD, NULL);
+    while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
+        pmFPAfile *file = item->data.V;
+        pmFPA *fpa = file->fpa;
+        fprintf (stderr, "file %s\n", file->name);
+        if (!fpa) {
+            fprintf (stderr, "  has no FPA\n");
+            continue;
+        }
+        if (fpa->hdu) {
+            if (fpa->hdu->images) fprintf (stderr, "  (%d,%d) images\n", -1, -1);
+            if (fpa->hdu->variances) fprintf (stderr, "  (%d,%d) variances\n", -1, -1);
+            if (fpa->hdu->masks) fprintf (stderr, "  (%d,%d) masks\n", -1, -1);
+            if (fpa->hdu->header) fprintf (stderr, "  (%d,%d) header\n", -1, -1);
+        } else {
+            // fprintf (stderr, "  has no fpa data (%d,%d)\n", -1, -1);
+        }
+        for (int i = 0; i < fpa->chips->n; i++) {
+            pmChip *chip = fpa->chips->data[i];
+            if (chip->hdu) {
+                if (chip->hdu->images) fprintf (stderr, "  (%d,%d) images\n", i, -1);
+                if (chip->hdu->variances) fprintf (stderr, "  (%d,%d) variances\n", i, -1);
+                if (chip->hdu->masks) fprintf (stderr, "  (%d,%d) masks\n", i, -1);
+                if (chip->hdu->header) fprintf (stderr, "  (%d,%d) header\n", i, -1);
+            } else {
+                // fprintf (stderr, "  has no chip data (%d,%d)\n", i, -1);
+            }
+            for (int j = 0; j < chip->cells->n; j++) {
+                pmCell *cell = chip->cells->data[j];
+                if (cell->hdu) {
+                    if (cell->hdu->images) fprintf (stderr, "  (%d,%d) images\n", i, j);
+                    if (cell->hdu->variances) fprintf (stderr, "  (%d,%d) variances\n", i, j);
+                    if (cell->hdu->masks) fprintf (stderr, "  (%d,%d) masks\n", i, j);
+                    if (cell->hdu->header) fprintf (stderr, "  (%d,%d) header\n", i, j);
+                } else {
+                    // fprintf (stderr, "  has no cell data (%d,%d)\n", i, j);
+                }
+                for (int k = 0; k < cell->readouts->n; k++) {
+                    pmReadout *readout = cell->readouts->data[k];
+                    if (readout) {
+                        if (readout->image) fprintf (stderr, "  (%d,%d,%d) image\n", i, j, k);
+                        if (readout->variance) fprintf (stderr, "  (%d,%d,%d) variance\n", i, j, k);
+                        if (readout->mask) fprintf (stderr, "  (%d,%d,%d) masks\n", i, j, k);
+                    }
+                }
+            }
+        }
+    }
+    psFree (iter);
+}
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotOptions.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotOptions.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotOptions.c	(revision 29947)
@@ -0,0 +1,258 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "psvideophot.h"
+
+static void imageOptionsFree(psvideophotOptions *options)
+{
+    psFree(options->overscan);
+    // psFree(options->nonLinearData);
+    // psFree(options->nonLinearSource);
+}
+
+psvideophotOptions *psvideophotOptionsAlloc(void)
+{
+    psvideophotOptions *options = psAlloc(sizeof(psvideophotOptions));
+    psMemSetDeallocator(options, (psFreeFunc)imageOptionsFree);
+
+    // actions which psvideophot should perform
+    options->doMaskBuild     = false;   // Build internal mask
+    options->doMaskSat       = false;   // mask saturated pixels
+    options->doMaskLow       = false;   // mask low pixels
+    options->doMaskBurntool  = false;   // mask potential burntool trails
+    options->doVarianceBuild = false;   // Build internal variance
+    options->doMask          = false;   // Mask bad pixels
+    options->doNonLin        = false;   // Non-linearity correction
+    options->doOverscan      = false;   // Overscan subtraction
+    options->doNoiseMap      = false;   // Apply Read Noise Map
+    options->doBias          = false;   // Bias subtraction
+    options->doDark          = false;   // Dark subtraction
+    options->doRemnance      = false;   // Remnance masking
+    options->doShutter       = false;   // Shutter correction
+    options->doFlat          = false;   // Flat-field normalisation
+    options->doPatternRow    = false;   // Row pattern correction
+    options->doPatternCell   = false;   // Cell pattern correction
+    options->doFringe        = false;   // Fringe subtraction
+    options->doPhotom        = false;   // Source identification and photometry
+    options->doAstromChip    = false;   // Astrometry (per-chip)
+    options->doAstromMosaic  = false;   // Astrometry (full-mosaic)
+    options->doStats         = false;   // Measure and save image statistics
+    options->checkCTE        = false;   // Measure pixel-based variance
+    options->applyParity     = false;   // Apply Cell parities
+    options->doMaskStats     = false;   // Calculate mask fractions
+    
+    // output files requested
+    options->BaseFITS        = false;   // create output image
+    options->BaseMaskFITS    = false;   // create output mask image
+    options->BaseVarianceFITS  = false;   // create output variance image
+
+    options->ChipFITS        = false;   // create output chip-mosaic image
+    options->ChipMaskFITS    = false;   // create output chip-mosaic mask image
+    options->ChipVarianceFITS  = false;   // create output chip-mosaic variance image
+
+    options->FPA1FITS        = false;   // create fpa-mosaic binned image (scale 1)
+    options->FPA2FITS        = false;   // create fpa-mosaic binned image (scale 2)
+    options->Bin1FITS        = false;   // create binned image (scale 1)
+    options->Bin2FITS        = false;   // create binned image (scale 2)
+    options->Bin1JPEG        = false;   // create jpeg of binned image (scale 1)
+    options->Bin2JPEG        = false;   // create jpeg of binned image (scale 2)
+
+    // default flags for various activities
+    options->maskValue       = 0x00;    // Default mask value (used to skip / ignore pixels)
+    options->satMask         = 0x00;    // Saturated pixels (supplied to pmReadoutGenerateMask)
+    options->lowMask         = 0x00;    // out-of-bounds (low) pixels (supplied to pmReadoutGenerateMask)
+    options->flatMask        = 0x00;    // Bad flat pixels (supplied to pmFlatField)
+    options->darkMask        = 0x00;    // Bad dark pixels (supplied to pmDarkApply)
+    options->blankMask       = 0x00;    // Blank (no data, cell gap) pixels (supplied to pmChipMosaic, pmFPAMosaic)
+    options->markValue       = 0x00;    // A safe bit for internal marking
+    options->burntoolMask    = 0x00;    // Suspect pixels that fall where a burntool trail is expected.
+    options->burntoolTrails  = 0x07;    // Which types of burntool areas to mask.
+    // crosstalk options
+    options->doCrosstalkMeasure = false;   // measure crosstalk
+    options->doCrosstalkCorrect = false;   // correct crosstalk
+
+    // Non-linearity default options
+    options->nonLinearType   = 0;       // Type of non-linearity data (vector, string or metadata)
+    options->nonLinearData   = NULL;    // The non-linearity data
+    options->nonLinearSource = NULL;    // If the non-linearity data is a menu, this provides the key
+
+    // Overscan defaults
+    options->overscan        = NULL;    // Overscan options
+
+    // binning parameters
+    options->xBin1           = 16;      // x-binning, scale 1
+    options->yBin1           = 16;      // y-binning, scale 1
+    options->xBin2           = 16;      // x-binning, scale 2
+    options->yBin2           = 16;      // y-binning, scale 2
+
+    // Fringe defaults
+    options->fringeRej       = NAN;     // Fringe rejection limit
+    options->fringeIter      = 0;       // Fringe iterations
+    options->fringeKeep      = 1.0;     // Fringe keep fraction
+
+    // Pattern correction values
+
+    options->patternRowOrder    = 0;       // Polynomial order
+    options->patternRowIter     = 0;       // Clipping iterations
+    options->patternRowRej      = NAN;     // Clipping rejection threshold
+    options->patternRowThresh   = NAN;     // Threshold for ignoring pixels
+    options->patternRowMean     = PS_STAT_NONE; // Statistic for mean
+    options->patternRowStdev    = PS_STAT_NONE; // Statistic for standard deviation
+    options->patternCellBG      = PS_STAT_NONE; // Statistic for background
+    options->patternCellMean    = PS_STAT_NONE; // Statistic for mean
+
+    // Remnance values
+    options->remnanceSize    = 30;      // Size for remnance detection
+    options->remnanceThresh  = 25.0;    // Threshold for remnance detection
+
+    // per-class normalization source
+    options->normClass       = NULL;    // per-class normalizations refer to this class
+
+    return options;
+}
+
+psvideophotOptions *psvideophotOptionsParse(pmConfig *config)
+{
+    bool status;
+    psvideophotOptions *options = psvideophotOptionsAlloc ();
+
+    // select the recipe for this analysis
+    bool mdStatus = false;              // Result of MD lookup
+    psMetadata *recipe = psMetadataLookupMetadata(&mdStatus, config->recipes, RECIPE_NAME);
+    if (! mdStatus || !recipe) {
+        psLogMsg("psvideophot", PS_LOG_ERROR, "Can't find recipe %s in the RECIPES.\n", RECIPE_NAME);
+        exit(EXIT_FAILURE);
+    }
+
+    // Non-linearity recipe options
+    if (psMetadataLookupBool(NULL, recipe, "NONLIN")) {
+        psMetadataItem *dataItem = psMetadataLookup(recipe, "NONLIN.DATA");
+        if (! dataItem) {
+            psLogMsg("psvideophot", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.DATA in recipe %s.", RECIPE_NAME);
+            exit(EXIT_FAILURE);
+        }
+
+        options->doNonLin = true;
+        options->nonLinearType = dataItem->type;
+        options->nonLinearData = dataItem;
+
+        switch (dataItem->type) {
+            // No immediate action required
+          case PS_DATA_VECTOR:
+          case PS_DATA_STRING:
+            break;
+
+            // This is a menu; we need the key
+          case PS_DATA_METADATA:
+	    options->nonLinearSource = psMetadataLookupStr(&status, recipe, "NONLIN.SOURCE");
+	    if (! status || ! options->nonLinearSource) {
+		psLogMsg("psvideophot", PS_LOG_ERROR, "Non-linearity correction desired, but unable to find NONLIN.SOURCE in recipe %s.", RECIPE_NAME);
+		exit(EXIT_FAILURE);
+	    }
+            break;
+          default:
+            psLogMsg("psvideophot", PS_LOG_ERROR, "Non-linearity correction desired, but NONLIN.DATA is of invalid type in recipe %s.", RECIPE_NAME);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    // XXX PAP: The overscan stuff needs to be updated following the reworked API
+
+    // Overscan recipe options
+    // XXX EAM : we should abort on invalid options. default options?
+    if (psMetadataLookupBool(NULL, recipe, "OVERSCAN")) {
+        options->doOverscan = true;
+
+        // Do the overscan as a single value?
+        bool overscanSingle = psMetadataLookupBool(NULL, recipe, "OVERSCAN.SINGLE");
+
+        // How do we fit it?
+        pmFit overscanFit = PM_FIT_NONE; // Fit type for overscan
+        int overscanOrder = 0;          // Order for overscan fit
+        psString fit = psMetadataLookupStr(NULL, recipe, "OVERSCAN.FIT");
+        if (! strcasecmp(fit, "POLYNOMIAL")) {
+            overscanFit = PM_FIT_POLY_ORD;
+            overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
+        } else if (! strcasecmp(fit, "CHEBYSHEV")) {
+            overscanFit = PM_FIT_POLY_CHEBY;
+            overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
+        } else if (! strcasecmp(fit, "SPLINE")) {
+            overscanFit = PM_FIT_SPLINE;
+        } else if (strcasecmp(fit, "NONE")) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "OVERSCAN.FIT (%s) in recipe %s is not one of NONE, POLYNOMIAL, or SPLINE",
+                     fit, RECIPE_NAME);
+            exit(EXIT_FAILURE);
+        }
+
+        // What method do we use to measure the overscan statistics?
+        // XXX allow user to specify psStats types by name
+        psStats *overscanStats = NULL;  // Statistics for overscan
+        psString stat = psMetadataLookupStr(NULL, recipe, "OVERSCAN.STAT");
+        if (! strcasecmp(stat, "MEAN")) {
+            // overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+            overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        } else if (! strcasecmp(stat, "MEDIAN")) {
+            overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
+        } else {
+            psErrorStackPrint(stderr, "OVERSCAN.STAT (%s) in recipe %s is not one of MEAN or MEDIAN",
+                              stat, RECIPE_NAME);
+            exit(EXIT_FAILURE);
+        }
+
+        int boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.BOXCAR");
+        float gauss = psMetadataLookupF32(NULL, recipe, "OVERSCAN.GAUSS");
+
+        // Fill in the options
+        options->overscan = pmOverscanOptionsAlloc(overscanSingle, overscanFit, overscanOrder,
+                                                   overscanStats, boxcar, gauss);
+
+        options->overscan->constant = psMetadataLookupBool(NULL, recipe, "OVERSCAN.CONSTANT");
+        options->overscan->value = psMetadataLookupF32(NULL, recipe, "OVERSCAN.VALUE");
+
+        psFree(overscanStats);
+    }
+
+    // for these images, even if not required otherwise
+    
+    options->doVarianceBuild = psMetadataLookupBool(NULL, recipe, "VARIANCE.BUILD");
+
+    // Mask recipe options (note that mask bit values are set in psvideophotSetMaskBits.c)
+    
+
+    // Mask recipe options (note that mask bit values are set in psvideophotSetMaskBits.c)
+    
+    options->doStats = false;
+    char *statsName = psMetadataLookupStr(&status, config->arguments, "STATS"); // Filename for statistics
+    if (statsName) {
+        options->doStats = true;
+    }
+
+        options->BaseFITS       = psMetadataLookupBool(NULL, recipe, "BASE.FITS");
+    options->BaseMaskFITS   = psMetadataLookupBool(NULL, recipe, "BASE.MASK.FITS");
+    options->BaseVarianceFITS = psMetadataLookupBool(NULL, recipe, "BASE.VARIANCE.FITS");
+
+    options->ChipFITS       = psMetadataLookupBool(NULL, recipe, "CHIP.FITS");
+    options->ChipMaskFITS   = psMetadataLookupBool(NULL, recipe, "CHIP.MASK.FITS");
+    options->ChipVarianceFITS = psMetadataLookupBool(NULL, recipe, "CHIP.VARIANCE.FITS");
+
+   
+    options->doPhotom       = psMetadataLookupBool(NULL, recipe, "PHOTOM");
+    options->doAstromChip   = psMetadataLookupBool(NULL, recipe, "ASTROM.CHIP");
+    options->doAstromMosaic = psMetadataLookupBool(NULL, recipe, "ASTROM.MOSAIC");
+    options->doBG           = psMetadataLookupBool(NULL, recipe, "BACKGROUND");
+
+    options->checkCTE       = psMetadataLookupBool(NULL, recipe, "CHECK.CTE");
+
+    // even if not requested explicitly, if any of these are set, build an internal mask and variance:
+    if (options->doNoiseMap || options->doBias || options->doOverscan || options->doDark || options->doShutter || options->doFlat ||
+        options->doPhotom) {
+        options->doMaskBuild = true;
+        options->doVarianceBuild = true;
+    } else if (options->doMask || options->doBG) {
+        options->doMaskBuild = true;
+    }
+
+    return options;
+}
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotParseCamera.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotParseCamera.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotParseCamera.c	(revision 29947)
@@ -0,0 +1,170 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+# include "psvideophot.h"
+
+psvideophotOptions *psvideophotParseCamera(pmConfig *config)
+{
+    bool status = false;
+
+    if (!psvideophotDefineFile(config, NULL, "PSVIDEOPHOT.INPUT", "INPUT", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_NONE)) {
+        psError(PS_ERR_IO, false, "Can't find an input image source");
+        return NULL;
+    }
+    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PSVIDEOPHOT.INPUT"); // Input file
+    psAssert(input, "We just put it there!");
+
+    // add recipe options supplied on command line
+    psMetadata *recipe  = psMetadataLookupPtr(&status, config->recipes, RECIPE_NAME);
+
+    // parse the options from the metadata format to the psvideophotOptions structure
+    psvideophotOptions *options = psvideophotOptionsParse(config);
+
+    // 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
+    
+    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS");
+    if (nThreads > 0) {
+        int nScanRows = psMetadataLookupS32(&status, recipe, "SCAN.ROWS");
+        pmDetrendSetThreadTasks(nScanRows);
+    }
+
+    // the following files are output targets
+    pmFPAfile *outImage = pmFPAfileDefineOutput(config, input->fpa, "PSVIDEOPHOT.OUTPUT");
+    if (!outImage) {
+        psError(PS_ERR_IO, false, _("Unable to generate output file from PSVIDEOPHOT.OUTPUT"));
+        psFree(options);
+        return NULL;
+    }
+    if (outImage->type != PM_FPA_FILE_OBJ) {
+        psError(PS_ERR_IO, true, "PSVIDEOPHOT.OUTPUT is not of type OBJ");
+        psFree(options);
+        return NULL;
+    }
+    
+    // XXX should these be bound explicitly to the outImage->fpa rather than the input->fpa?
+    pmFPAfile *chipImage = pmFPAfileDefineChipMosaic(config, input->fpa, "PSVIDEOPHOT.CHIP");
+    if (!chipImage) {
+        psError(PS_ERR_IO, false, _("Unable to generate new file from PSVIDEOPHOT.CHIP"));
+        psFree(options);
+        return NULL;
+    }
+    if (chipImage->type != PM_FPA_FILE_OBJ) {
+        psError(PS_ERR_IO, true, "PSVIDEOPHOT.CHIP is not of type OBJ");
+        psFree(options);
+        return NULL;
+    }
+    
+
+    // chipImage    -> psphotInput  (pmFPAfileDefineFromFile)       : fpa is constructed
+    // psphotInput  -> psphotOutput (pmFPAfileDefineOutputFromFile) : fpa is equated
+    // psphotOutput -> psastroInput (pmFPAfileDefineInput)          : fpa is ref-copied
+    // psastroInput -> psastroModel (pmFPAfileDefineFromArgs        : fpa is ref-copied
+    // psastroInput -> psastroModel (pmFPAfileDefineFromConf        : fpa is constructed
+    // psastroInput -> psastroModel (pmFPAfileDefineFromDetDB       : fpa is constructed (pmDetrendSelect uses input concepts )
+
+    // For photometry, we operate on the chip-mosaicked image
+    // we create a copy of the mosaicked image for psphot so we can write out a clean image
+    
+
+        // this file is just used as a carrier; output files (eg, PSPHOT.RESID) are defined by
+        // psphotDefineFiles
+        pmFPAfile *psphotInput = pmFPAfileDefineFromFile (config, chipImage, 1, 1, "PSPHOT.INPUT");
+        PS_ASSERT (psphotInput, false);
+
+        // specify the number of psphot input images
+        psMetadataAddS32 (config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "number of inputs", 1);
+
+        // define associated psphot input/output files
+        if (!psphotDefineFiles (config, psphotInput)) {
+            psError(PSPHOT_ERR_CONFIG, false,
+                    "Trouble defining the additional input/output files for psphot");
+            return false;
+        }
+    
+
+    // For photometry, we operate on the chip-mosaicked image
+    
+
+    // save any of these files?
+    outImage->save   = options->BaseFITS;
+    
+
+    chipImage->save  = options->ChipFITS;
+    
+
+    
+    // outImage is used as a carrier: input to chipImage -> require the data to remain at the CHIP level
+    outImage->freeLevel = PS_MIN(outImage->freeLevel, PM_FPA_LEVEL_CHIP);
+    outImage->dataLevel = outImage->freeLevel;
+    outImage->fileLevel = PS_MIN(outImage->fileLevel, outImage->dataLevel);
+
+    // outMask and outVariance must be freed at the same level as outImage (all freed by pmFPAFreeData)
+    
+
+    // the input data is the same as the outImage data : force the free levels to match
+    input->freeLevel = PS_MIN(outImage->freeLevel, input->freeLevel);
+
+    // define the binned target files (which may just be carriers for some camera configurations)
+    
+    // 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);
+                psFree(options);
+                return false;
+            }
+        }
+    }
+    psFree (chips);
+
+    if (psMetadataLookupBool(NULL, config->arguments, "INPUT_IS_FRINGE")) {
+        // It's a fringe file, so change the file type
+        input->type = PM_FPA_FILE_FRINGE;
+        outImage->type = PM_FPA_FILE_FRINGE;
+    }
+    if (psMetadataLookupBool(NULL, config->arguments, "INPUT_IS_DARK")) {
+        // It's a dark file, so change the file type
+        input->type = PM_FPA_FILE_DARK;
+        outImage->type = PM_FPA_FILE_DARK;
+        // Turn off compression --- there are just too many nasties that can happen
+        psFree(outImage->compression);
+        outImage->compression = NULL;
+        psFree(outImage->options);
+        outImage->options = NULL;
+    }
+
+    // Turn off mask and variance output if we're not doing anything interesting
+    
+    if (psTraceGetLevel("psvideophot.config") > 0) {
+        // Get a look inside all the files.
+        psMetadataIterator *filesIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, NULL);
+        psMetadataItem *item;               // Item from iteration
+        fprintf(stderr, "Files:\n");
+        while ((item = psMetadataGetAndIncrement(filesIter))) {
+            pmFPAfile *file = item->data.V; // File of interest
+            fprintf(stderr, "%s: %p %p %p (%p) %p\n", file->name,
+                    file->src, file->fpa,
+                    file->camera, file->fpa->camera, file->format);
+        }
+        psFree(filesIter);
+    }
+
+    // Change the input dark type between the old (IMAGE) and new (multi-DARK).
+    // Hopefully this is a temporary change until we all move over to using the new dark types
+    bool mdok;                          // Status of MD lookup
+    if (options->doDark && psMetadataLookupBool(&mdok, recipe, "OLDDARK")) {
+        pmFPAfile *dark = psMetadataLookupPtr(NULL, config->files, "PSVIDEOPHOT.DARK");
+        assert(dark);
+        dark->type = PM_FPA_FILE_IMAGE;
+    }
+
+    return (options);
+}
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersion.c
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersion.c	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersion.c	(revision 29947)
@@ -0,0 +1,115 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "psvideophot.h"
+#include "psvideophotVersionDefinitions.h"
+
+#ifndef PSVIDEOPHOT_VERSION
+#error "PSVIDEOPHOT_VERSION is not set"
+#endif
+#ifndef PSVIDEOPHOT_BRANCH
+#error "PSVIDEOPHOT_BRANCH is not set"
+#endif
+#ifndef PSVIDEOPHOT_SOURCE
+#error "PSVIDEOPHOT_SOURCE is not set"
+#endif
+
+psString psvideophotVersion(void)
+{
+    char *value = NULL;
+    psStringAppend(&value, "%s@%s", PSVIDEOPHOT_BRANCH, PSVIDEOPHOT_VERSION);
+    return value;
+}
+
+psString psvideophotSource(void)
+{
+    return psStringCopy(PSVIDEOPHOT_SOURCE);
+}
+
+psString psvideophotVersionLong(void)
+{
+    psString version = psvideophotVersion();  // Version, to return
+    psString source = psvideophotSource(); // Source
+
+    psStringPrepend(&version, "psvideophot ");
+    psStringAppend(&version, " from %s, built %s, %s", source, __DATE__, __TIME__);
+    psFree(source);
+
+#ifdef __OPTIMIZE__
+    psStringAppend(&version, " optimised");
+#else
+    psStringAppend(&version, " unoptimised");
+#endif
+
+    return version;
+};
+
+bool psvideophotVersionHeader(psMetadata *header)
+{
+    PS_ASSERT_METADATA_NON_NULL(header, false);
+
+    psTime *time = psTimeGetNow(PS_TIME_TAI); // The time now
+    psString timeString = psTimeToISO(time); // The time in an ISO string
+    psFree(time);
+    psString history = NULL;               // History string
+    psStringAppend(&history, "psvideophot at %s", timeString);
+    psFree(timeString);
+    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, history);
+    psFree(history);
+
+    psLibVersionHeader(header);
+    psModulesVersionHeader(header);
+    psphotVersionHeader(header);
+    psastroVersionHeader(header);
+    ppStatsVersionHeader(header);
+
+    psString version = psvideophotVersion(); // psvideophot software version
+    psString source  = psvideophotSource();  // psvideophot software source
+
+    psMetadataAddStr(header, PS_LIST_TAIL, "IMAGE_V", PS_META_REPLACE, NULL, PSVIDEOPHOT_VERSION);
+    
+    psStringPrepend(&version, "psvideophot version: ");
+    psStringPrepend(&source, "psvideophot source: ");
+
+    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, version);
+    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, source);
+
+    psFree(version);
+    psFree(source);
+
+    return true;
+}
+
+
+void psvideophotVersionPrint(void)
+{
+    psTime *time = psTimeGetNow(PS_TIME_TAI); // The time now
+    psString timeString = psTimeToISO(time); // The time in an ISO string
+    psFree(time);
+    psLogMsg("psvideophot", PS_LOG_INFO, "psvideophot at %s", timeString);
+    psFree(timeString);
+
+    psString pslib = psLibVersionLong();// psLib version
+    psString psmodules = psModulesVersionLong(); // psModules version
+    psString psphot = psphotVersionLong(); // psphot version
+    psString psastro = psastroVersionLong(); // psastro version
+    psString ppStats = ppStatsVersionLong(); // ppStats version
+    psString psvideophot = psvideophotVersionLong(); // psvideophot version
+
+    psLogMsg("psvideophot", PS_LOG_INFO, "%s", pslib);
+    psLogMsg("psvideophot", PS_LOG_INFO, "%s", psmodules);
+    psLogMsg("psvideophot", PS_LOG_INFO, "%s", psphot);
+    psLogMsg("psvideophot", PS_LOG_INFO, "%s", psastro);
+    psLogMsg("psvideophot", PS_LOG_INFO, "%s", ppStats);
+    psLogMsg("psvideophot", PS_LOG_INFO, "%s", psvideophot);
+
+    psFree(pslib);
+    psFree(psmodules);
+    psFree(psphot);
+    psFree(psastro);
+    psFree(ppStats);
+    psFree(psvideophot);
+
+    return;
+}
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersionDefinitions.h
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersionDefinitions.h	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersionDefinitions.h	(revision 29947)
@@ -0,0 +1,8 @@
+#ifndef PSVIDEOPHOT_VERSION_DEFINITIONS_H
+#define PSVIDEOPHOT_VERSION_DEFINITIONS_H
+
+#define PSVIDEOPHOT_VERSION "29871:29881M" // SVN version
+#define PSVIDEOPHOT_BRANCH  "branches/haf_branches/videophot2010/ppImage"  // SVN branch
+#define PSVIDEOPHOT_SOURCE  "60eb6cdc-a59c-4636-a4e0-dba66a9721fd"  // SVN source
+
+#endif
Index: /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersionDefinitions.h.in
===================================================================
--- /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersionDefinitions.h.in	(revision 29947)
+++ /branches/haf_branches/videophot2010/ppImage/src/psvideophotVersionDefinitions.h.in	(revision 29947)
@@ -0,0 +1,8 @@
+#ifndef PSVIDEOPHOT_VERSION_DEFINITIONS_H
+#define PSVIDEOPHOT_VERSION_DEFINITIONS_H
+
+#define PSVIDEOPHOT_VERSION @PSVIDEOPHOT_VERSION@ // SVN version
+#define PSVIDEOPHOT_BRANCH  @PSVIDEOPHOT_BRANCH@  // SVN branch
+#define PSVIDEOPHOT_SOURCE  @PSVIDEOPHOT_SOURCE@  // SVN source
+
+#endif
