Index: /trunk/pswarp/src/pswarpHeadersLoad.c
===================================================================
--- /trunk/pswarp/src/pswarpHeadersLoad.c	(revision 12528)
+++ /trunk/pswarp/src/pswarpHeadersLoad.c	(revision 12528)
@@ -0,0 +1,105 @@
+# include "pswarp.h"
+
+// XXX this function should load all of the PSWARP.INPUT headers
+// it should examine the overlap between each chip in PSWARP.INPUT 
+// and the output (pswarpMatchRange) and select/de-select the chips
+// and/or cell which contribute pixels.  
+
+// pswarpDataLoad should then load the pixel of the needed chips
+
+// all of the different astrometry analysis modes use the same data load loop
+bool pswarpHeadersLoad (pmConfig *config) {
+
+    pmChip *chip;
+    pmCell *cell;
+    pmReadout *readout;
+    pmFPAview *view;
+
+    // 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;
+    }
+
+    // use the external astrometry source if supplied
+    pmFPAfile *astrom = psMetadataLookupPtr (NULL, config->files, "PSWARP.ASTROM");
+    if (!astrom) {
+	astrom = input;
+    }
+ 
+    // select the output readout
+    view = pmFPAviewAlloc (0);
+    view->chip = 0;
+    view->cell = 0;
+    view->readout = 0;
+    pmReadout  *output = pmFPAfileThisReadout (config->files, view, "PSWARP.OUTPUT");
+    if (!output) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find output data!\n");
+	return false;
+    }
+    psFree (view);
+
+    // de-activate PSWARP.SKYCELL and PSWARP.OUTPUT
+    pmFPAfileActivate (config->files, false, "PSWARP.SKYCELL");
+    pmFPAfileActivate (config->files, false, "PSWARP.OUTPUT");
+
+    view = pmFPAviewAlloc (0);
+
+    // XXX need to read only the headers for the skycell
+    // XXX these pmAstromReadBilevel functions seem to be broken
+
+    // find the FPA phu
+    bool bilevelAstrometry = false;
+    pmHDU *phu = pmFPAviewThisPHU (view, astrom->fpa);
+    if (phu) {
+	char *ctype = psMetadataLookupStr (NULL, phu->header, "CTYPE1");
+	if (ctype) {
+	    bilevelAstrometry = !strcmp (&ctype[4], "-DIS");
+	}
+    }
+    if (bilevelAstrometry) {
+	pmAstromReadBilevelMosaic (input->fpa, phu->header);
+    } 
+
+    // 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);
+
+        // read WCS data from the corresponding header
+	pmHDU *hdu = pmFPAviewThisHDU (view, astrom->fpa);
+	if (bilevelAstrometry) {
+	    pmAstromReadBilevelChip (chip, hdu->header); 
+	} else {
+	    // we use a default FPA pixel scale of 1.0
+	    pmAstromReadWCS (input->fpa, chip, hdu->header, 1.0);
+	}
+
+	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; }
+
+		// XXX Replace with a function to examine the overlap and turn on/off chips 
+		// based on that result
+		// pswarpTransformReadout_Opt (output, 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;
+}
Index: /trunk/pswarp/src/pswarpTransformReadout_Opt.c
===================================================================
--- /trunk/pswarp/src/pswarpTransformReadout_Opt.c	(revision 12527)
+++ /trunk/pswarp/src/pswarpTransformReadout_Opt.c	(revision 12528)
@@ -1,16 +1,42 @@
 # include "pswarp.h"
+psImageInterpolateMode psImageInterpolateModeFromString (char *name);
 
 // NOTE: in this function, the coordinates are transformed from the OUTPUT to the INPUT
 bool pswarpTransformReadout_Opt (pmReadout *output, pmReadout *input, pmConfig *config) {
 
+    bool status;
     int minX, minY, maxX, maxY;
     int gridXo, gridX, gridY, nextGridXo, nextGridX, nextGridY;
     pswarpMap *map = NULL;
+    psImageInterpolateMode interpolationMode = PS_INTERPOLATE_NONE;
 
     // XXX this implementation currently ignores the use of the region 
     psImage *region = NULL;
 
+    psTimerStart ("warp");
+
     // select the current recipe
-    // psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
+    psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find PSWARP recipe!\n");
+	return false;
+    }
+    
+    int nGridX = psMetadataLookupS32 (&status, recipe, "GRID.NX");
+    if (!status) nGridX = 128;
+    int nGridY = psMetadataLookupS32 (&status, recipe, "GRID.NY");
+    if (!status) nGridY = 128;
+
+    char *name = psMetadataLookupStr (&status, recipe, "INTERPOLATION.MODE");
+    if (!name) {
+	interpolationMode = PS_INTERPOLATE_BILINEAR;
+	psLogMsg ("pswarp", 3, "defaulting to bilinear interpolation\n");
+    } else {
+	interpolationMode = psImageInterpolateModeFromString (name);
+	if (interpolationMode == PS_INTERPOLATE_NONE) {
+	    interpolationMode = PS_INTERPOLATE_BILINEAR;
+	    psLogMsg ("pswarp", 3, "unknown interpolation mode %s, defaulting to bilinear interpolation\n", name);
+	}
+    }
 
     psPlane *inPix = psPlaneAlloc();	// Coordinates on the input detector
@@ -33,5 +59,5 @@
     // pswarpMapGridFromImage builds a set of locally-linear maps which convert the
     // output coordinates to input coordinates
-    pswarpMapGrid *grid = pswarpMapGridFromImage (input, output, 128, 128);
+    pswarpMapGrid *grid = pswarpMapGridFromImage (input, output, nGridX, nGridY);
 
     // XXX need to modify the grid based on this result and force the maxError < XXX
@@ -81,9 +107,8 @@
 	    if (inPix->y - inRow0 >= inImage->numRows) continue;
 
-	    // XXX get interpolation method from the recipe
 	    // XXX include mask
 	    // XXX apply scale and offset?
 	    // psImagePixelInterpolate determines the value at pixel coordinate (x,y) in child coordinates 
-	    outData[y-outRow0][x-outCol0] = (psF32)psImagePixelInterpolate(inImage, inPix->x - inCol0, inPix->y - inRow0, NULL, 1, NAN, PS_INTERPOLATE_BILINEAR);
+	    outData[y-outRow0][x-outCol0] = (psF32)psImagePixelInterpolate(inImage, inPix->x - inCol0, inPix->y - inRow0, NULL, 1, NAN, interpolationMode);
 	}
     }
@@ -91,4 +116,6 @@
     psFree (inPix);
     psFree (grid);
+    psLogMsg ("pswarp", 3, "warping analysis: %f sec\n", psTimerMark ("warp"));
+
     return true;
 }
