Index: /trunk/pswarp/doc/notes.txt
===================================================================
--- /trunk/pswarp/doc/notes.txt	(revision 10832)
+++ /trunk/pswarp/doc/notes.txt	(revision 10832)
@@ -0,0 +1,29 @@
+
+- pswarp takes an image (and corresponding mask and weight images) and
+  warps the pixels to match the specified skycell projection and pixel
+  grid.  the astrometry of the input image is supplied by the header
+  of the image or by a specified SMP file. 
+
+- the input image, weight, mask are loaded into pmFPA structures with
+  the layout determined by the camera/format/layout
+
+- the skycell is loaded into a pmFPA structure.  at a minimum, a
+  single skycell may contain a single chip, cell, and readout, which
+  in turn correspond to the single set of pixels representing the
+  image region.  
+
+  * is there a need or use for a skycell to have a multilayered
+    structure equivalent in any way to the fpa->chip->cell->readout
+    layer?
+
+    - perhaps we will want to use a single fpa for a larger region
+      with small sky cells representing contiguous pixel regions.  
+
+    - perhaps we will want to warp an entire fpa exposure at once and
+      use a skyfpa to represent all of the possible output skycells
+      for a single input fpa exposure.
+
+- the output is a file or set of files corresponding to the skycell
+  files.  the details should be specified by the PSWARP.OUTPUT file
+  rule.
+
Index: /trunk/pswarp/src/pswarp.c
===================================================================
--- /trunk/pswarp/src/pswarp.c	(revision 10832)
+++ /trunk/pswarp/src/pswarp.c	(revision 10832)
@@ -0,0 +1,38 @@
+# include "pswarp.h"
+
+static void usage (void) {
+    fprintf (stderr, "USAGE: pswarp [-file image(s)] [-list imagelist] [options] (output) (skycell)\n");
+    fprintf (stderr, "  options:\n");
+    fprintf (stderr, "    [-astrom astrom.cmp] : provide an alternative astrometry calibration\n");
+    fprintf (stderr, "    [-mask mask.fits] : provide a corresponding mask image\n");
+    fprintf (stderr, "    [-weight weight.fits] : provide a corresponding weight image (pixel varience)\n");
+    psErrorStackPrint(stderr, "");
+    exit (2);
+}
+
+int main (int argc, char **argv) {
+
+    psTimerStart ("complete");
+
+    pmConfig *config = pswarpArguments (argc, argv);
+    if (!config) usage ();
+
+    // load identify the data sources
+    if (!psastroParseCamera (config)) {
+	psErrorStackPrint(stderr, "error setting up the camera\n");
+	exit (1);
+    }
+
+    // load the skycell layout information
+    pswarpDefine ();
+
+    // warp loop 
+    pswarpProcess ();
+    
+    // write out result image
+    pswarpDataSave ();
+
+    psLogMsg ("pswarp", 3, "complete pswarp run: %f sec\n", psTimerMark ("complete"));
+    pswarpCleanup (config, refs);
+    exit (EXIT_SUCCESS);
+}
Index: /trunk/pswarp/src/pswarpArguments.c
===================================================================
--- /trunk/pswarp/src/pswarpArguments.c	(revision 10832)
+++ /trunk/pswarp/src/pswarpArguments.c	(revision 10832)
@@ -0,0 +1,65 @@
+# include "pswarp.h"
+# include <glob.h>
+
+pmConfig *pswarpArguments (int argc, char **argv) {
+
+    bool status;
+    int N;
+
+    if (argc == 1) {
+	psError(PSWARP_ERR_ARGUMENTS, true, "No arguments supplied");
+	return NULL;
+    }
+
+    // load config data from default locations
+    pmConfig *config = pmConfigRead(&argc, argv, PSWARP_RECIPE);
+    if (config == NULL) {
+        psError(PSWARP_ERR_CONFIG, false, "Can't read site configuration");
+        return NULL;
+    }
+
+    // save the following additional recipe values based on command-line options
+    // these options override the PSWARP recipe values loaded from recipe files
+    psMetadata *options = pmConfigRecipeOptions (config, PSWARP_RECIPE);
+
+    // astrom : used to supply astrometric parameters
+    if ((N = psArgumentGet (argc, argv, "-astrom"))) {
+        psArgumentRemove (N, &argc, argv);
+        psMetadataAddStr (options, PS_LIST_TAIL, "ASTROM_SOURCE", PS_META_REPLACE, "", argv[N]);
+        psArgumentRemove (N, &argc, argv);
+    }
+
+    // chip selection is used to limit chips to be processed
+    if ((N = psArgumentGet (argc, argv, "-chip"))) {
+        psArgumentRemove (N, &argc, argv);
+        psMetadataAddStr (config->arguments, PS_LIST_TAIL, "CHIP_SELECTIONS", PS_DATA_STRING, "", psStringCopy(argv[N]));
+        psArgumentRemove (N, &argc, argv);
+    }
+
+    // drop the local view on the options (saved in config->arguments)
+    psFree (options);
+
+    status = pmConfigFileSetsMD (config->arguments, config, "INPUT", "-file", "-list");
+    if (!status) {
+	psError(PSWARP_ERR_ARGUMENTS, true, "Missing -file (input) or -list (input)");
+	return NULL;
+    }
+    
+    // the mask and weight entries are optional (build from gain?)
+    pmConfigFileSetsMD (config->arguments, config, "MASK",   "-mask",   "-masklist");
+    pmConfigFileSetsMD (config->arguments, config, "WEIGHT", "-weight", "-weightlist");
+    
+    if (argc != 2) {
+	psError(PSWARP_ERR_ARGUMENTS, true, "Incorrect arguments supplied");
+	return NULL;
+    }
+    
+    // output position is fixed
+    psMetadataAddStr (config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "", argv[1]);
+
+    // skycell position is fixed
+    psMetadataAddStr (config->arguments, PS_LIST_TAIL, "SKYCELL", 0, "", argv[2]);
+
+    psTrace("pswarp", 1, "Done with pswarpArguments...\n");
+    return (config);
+}
Index: /trunk/pswarp/src/pswarpDefine.c
===================================================================
--- /trunk/pswarp/src/pswarpDefine.c	(revision 10832)
+++ /trunk/pswarp/src/pswarpDefine.c	(revision 10832)
@@ -0,0 +1,40 @@
+# include "pswarp.h"
+// this function loads the skycell metadata
+
+bool pswarpDefine (pmConfig *config) {
+
+    // select the current recipe
+    psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find PSWARP recipe!\n");
+	return false;
+    }
+
+    // select the input data sources
+    pmFPAfile *skycell = psMetadataLookupPtr (NULL, config->files, "PSWARP.SKYCELL");
+    if (!skycell) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find skycell data!\n");
+	return false;
+    }
+
+    // XXX drop? de-activate all files except PSWARP.INPUT
+    // pmFPAfileActivate (config->files, false, NULL);
+    // pmFPAfileActivate (config->files, true, "PSWARP.INPUT");
+
+    // open the full skycell file; no need to defer different depths
+    pmFPAview *view = pmFPAviewAlloc (0);
+    pmFPAfileOpen (skycell, view, config);
+    pmFPAfileRead (skycell, view, config);
+
+    // construct the output fpa here
+    pmFPAfile *output = psMetadataLookupPtr (NULL, config->files, "PSWARP.OUTPUT");
+    if (!output) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find output data!\n");
+	return false;
+    }
+
+    pmFPAfileCreate (output, view, config);
+
+    psFree (view);
+    return true;
+}
Index: /trunk/pswarp/src/pswarpParseCamera.c
===================================================================
--- /trunk/pswarp/src/pswarpParseCamera.c	(revision 10832)
+++ /trunk/pswarp/src/pswarpParseCamera.c	(revision 10832)
@@ -0,0 +1,56 @@
+# include "pswarp.h"
+
+bool pswarpParseCamera (pmConfig *config) {
+
+    bool status = false;
+
+    // the input image(s) are required arguments; they define the camera
+    pmFPAfile *input = pmFPAfileDefineFromArgs (&status, config, "PSWARP.INPUT", "INPUT");
+    if (!status) {
+	psError(PSWARP_ERR_CONFIG, false, "Failed to build FPA from PSWARP.INPUT");
+	return false;
+    }
+
+    // select recipe options supplied on command line
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSWARP_RECIPE);
+
+    // the input skycell is a required argument: it defines the output image
+    pmFPAfile *skycell = pmFPAfileDefineFromArgs (&status, config, "PSWARP.SKYCELL", "SKYCELL");
+    if (!status) {
+	psError(PSWARP_ERR_CONFIG, false, "Failed to build FPA from PSWARP.INPUT");
+	return false;
+    }
+
+    // the mask is not required; the  skycell is a required argument: it defines the output image
+    pmFPAfileDefineFromArgs (&status, config, "PSWARP.MASK", "MASK");
+    if (!status) {
+      // build the basic mask concept here
+    }
+
+    // the weight is not required; the  skycell is a required argument: it defines the output image
+    pmFPAfileDefineFromArgs (&status, config, "PSWARP.WEIGHT", "WEIGHT");
+    if (!status) {
+      // build the basic weight concept here
+    }
+
+    // these calls bind the I/O handle to the specified fpa
+    pmFPAfileDefineOutput (config, skycell->fpa, "PSWARP.OUTPUT");
+
+    // Chip selection: turn on only the chips specified
+    char *chipLine = psMetadataLookupStr(NULL, 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(PSWARP_ERR_CONFIG, true, "Chip number %d doesn't exist in camera.\n", chipNum);
+		return false;
+	    }
+        }
+    }
+    psFree (chips);
+
+    psTrace("pswarp", 1, "Done with pswarpParseCamera...\n");
+    return true;
+}
Index: /trunk/pswarp/src/pswarpProcess.c
===================================================================
--- /trunk/pswarp/src/pswarpProcess.c	(revision 10832)
+++ /trunk/pswarp/src/pswarpProcess.c	(revision 10832)
@@ -0,0 +1,58 @@
+# include "pswarp.h"
+// this loop loads the data from the input files and selects the
+// brighter stars for astrometry
+// at the end of this function, the complete stellar data is loaded
+// into the correct fpa structure locations (readout.analysis:PSPHOT.SOURCES)
+
+// all of the different astrometry analysis modes use the same data load loop
+bool pswarpDataLoad (pmConfig *config) {
+
+    pmChip *chip;
+    pmCell *cell;
+    pmReadout *readout;
+
+    // select the input data sources
+    pmFPAfile *input = psMetadataLookupPtr (NULL, config->files, "PSWARP.INPUT");
+    if (!input) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find input data!\n");
+	return false;
+    }
+
+    // de-activate PSWARP.SKYCELL and PSWARP.OUTPUT
+    // 
+    pmFPAfileActivate (config->files, false, "PSWARP.OUTPUT");
+    pmFPAfileActivate (config->files, false, "PSWARP.SKYCELL");
+
+    pmFPAview *view = pmFPAviewAlloc (0);
+
+    // files associated with the science image
+    pmFPAfileIOChecks (config, view, PM_FPA_BEFORE);
+
+    while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
+        psTrace ("pswarp", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process || !chip->file_exists) { continue; }
+	pmFPAfileIOChecks (config, view, PM_FPA_BEFORE);
+
+	while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
+            psTrace ("pswarp", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+            if (!cell->process || !cell->file_exists) { continue; }
+	    pmFPAfileIOChecks (config, view, PM_FPA_BEFORE);
+
+	    // process each of the readouts
+	    while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
+		pmFPAfileIOChecks (config, view, PM_FPA_BEFORE);
+		if (! readout->data_exists) { continue; }
+
+		pswarpConvertReadout (readout, config);
+
+		pmFPAfileIOChecks (config, view, PM_FPA_AFTER);
+	    }
+	    pmFPAfileIOChecks (config, view, PM_FPA_AFTER);
+	}
+	pmFPAfileIOChecks (config, view, PM_FPA_AFTER);
+    }
+    pmFPAfileIOChecks (config, view, PM_FPA_AFTER);
+    psFree (view);
+    return true;
+}
+
