Index: trunk/ppViz/src/ppCoord/ppCoord.h
===================================================================
--- trunk/ppViz/src/ppCoord/ppCoord.h	(revision 42229)
+++ trunk/ppViz/src/ppCoord/ppCoord.h	(revision 42253)
@@ -14,4 +14,5 @@
     psString rawName;                   // Filename with raw image (or NULL)
     psString pixelsName;                // Filename with pixel coordinates
+    psString fpaName;                   // Filename with FPA coordinates
     psString chipName;                  // Name of chip of interest
     psString radecName;                 // Filename with sky coordinates
Index: trunk/ppViz/src/ppCoord/ppCoordArguments.c
===================================================================
--- trunk/ppViz/src/ppCoord/ppCoordArguments.c	(revision 42229)
+++ trunk/ppViz/src/ppCoord/ppCoordArguments.c	(revision 42253)
@@ -49,4 +49,5 @@
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-raw", 0, "Filename with raw data", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-pixels", 0, "Filename with pixel coordinates", NULL);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-fpa", 0, "Filename with FPA coordinates", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-chip", 0, "Chip for pixel coordinates", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-radec", 0, "Filename with RA,Dec (default decimal degrees)", NULL);
@@ -66,4 +67,5 @@
     data->rawName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-raw"));
     data->pixelsName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-pixels"));
+    data->fpaName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-fpa"));
     data->chipName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-chip"));
     data->radecName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-radec"));
@@ -96,6 +98,6 @@
     }
 
-    if (!data->pixelsName && !data->radecName && !data->streaksName && !data->clustersName) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Neither -pixels nor -radec provided.");
+    if (!data->pixelsName && !data->radecName && !data->fpaName && !data->streaksName && !data->clustersName) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Neither -pixels nor -radec nor -fpa provided.");
         return false;
     }
Index: trunk/ppViz/src/ppCoord/ppCoordData.c
===================================================================
--- trunk/ppViz/src/ppCoord/ppCoordData.c	(revision 42229)
+++ trunk/ppViz/src/ppCoord/ppCoordData.c	(revision 42253)
@@ -16,4 +16,5 @@
     psFree(data->rawName);
     psFree(data->pixelsName);
+    psFree(data->fpaName);
     psFree(data->chipName);
     psFree(data->radecName);
@@ -37,4 +38,5 @@
     data->rawName = NULL;
     data->pixelsName = NULL;
+    data->fpaName = NULL;
     data->chipName = NULL;
     data->radecName = NULL;
Index: trunk/ppViz/src/ppCoord/ppCoordLoop.c
===================================================================
--- trunk/ppViz/src/ppCoord/ppCoordLoop.c	(revision 42229)
+++ trunk/ppViz/src/ppCoord/ppCoordLoop.c	(revision 42253)
@@ -79,6 +79,6 @@
         NULL; // File with raw image
 
-    psArray *pixels = NULL, *radec = NULL, *streaks = NULL, *clusters = NULL; // Array of coordinate vectors
-    psArray *radecOut = NULL, *streaksOut = NULL, *clustersOut = NULL;        // Output for sky coordinates
+    psArray *pixels = NULL, *radec = NULL, *fpas = NULL, *streaks = NULL, *clusters = NULL; // Array of coordinate vectors
+    psArray *radecOut = NULL,*fpaOut = NULL, *streaksOut = NULL, *clustersOut = NULL;        // Output for sky coordinates
     if (data->pixelsName) {
         pixels = psVectorsReadFromFile(data->pixelsName, "%f %f");
@@ -107,4 +107,25 @@
         psVectorInit(radecOut->data[1], NAN);
         psVectorInit(radecOut->data[2], NAN);
+    }
+
+    if (data->fpaName) {
+        fpas = psVectorsReadFromFile(data->fpaName, "%f %f");
+        if (!fpas || fpas->n != 2) {
+            psError(psErrorCodeLast(), false, "Unable to read FPA coordinates");
+            return false;
+        }
+        psVector *fpa_x = fpas->data[0];  // FPA x coordinates
+        long num = fpa_x->n;               // Number of coordinates
+        fpaOut = psArrayAlloc(6);
+        fpaOut->data[0] = psArrayAlloc(num);
+        fpaOut->data[1] = psVectorAlloc(num, PS_TYPE_F32);
+        fpaOut->data[2] = psVectorAlloc(num, PS_TYPE_F32);
+        fpaOut->data[3] = psArrayAlloc(num);
+        fpaOut->data[4] = psVectorAlloc(num, PS_TYPE_F32);
+        fpaOut->data[5] = psVectorAlloc(num, PS_TYPE_F32);
+        psVectorInit(fpaOut->data[1], NAN);
+        psVectorInit(fpaOut->data[2], NAN);
+        psVectorInit(fpaOut->data[4], NAN);
+        psVectorInit(fpaOut->data[5], NAN);
     }
 
@@ -394,4 +415,59 @@
 		yTP->data.F32[i] = src.tp.y;
             }
+        }
+
+        if (fpas) {
+            psVector *fpa_x = fpas->data[0], *fpa_y = fpas->data[1]; // FPA coordinates
+            long num = fpa_x->n;                                     // Number of coordinates
+
+            int numCols = psMetadataLookupS32(NULL, hdu->header, "IMNAXIS1"); // Number of columns
+            int numRows = psMetadataLookupS32(NULL, hdu->header, "IMNAXIS2"); // Number of rows
+            if (numCols <= 0 || numRows <= 0) {
+                psError(psErrorCodeLast(), false, "Unable to read size of chip.");
+                return false;
+            }
+
+            psArray *chipPix = fpaOut->data[0]; // Chip for pixels
+            psVector *xPix = fpaOut->data[1];   // x coordinate for pixels
+            psVector *yPix = fpaOut->data[2];   // y coordinate for pixels
+            psArray *cellPix = fpaOut->data[3]; // Cell for pixels
+            psVector *xCell = fpaOut->data[4];   // x coordinate for cell
+            psVector *yCell = fpaOut->data[5];   // y coordinate for cell
+
+            psPlane *pix = psPlaneAlloc();   // Pixel coordinates on chip
+            psPlane *fp = psPlaneAlloc();    // Focal plane coordinates
+
+            for (long i = 0; i < num; i++) {
+                float x, y;             // Pixel coordinates
+                fp->x = fpa_x->data.F32[i];
+                fp->y = fpa_y->data.F32[i];
+
+                psPlaneTransformApply(pix, chip->fromFPA, fp);
+                psTrace("ppCoord",2,"fpa2pix tr1: %f %f\n",pix->x,pix->y);
+
+                x = pix->x;
+                y = pix->y;
+
+                if ((x < 0 || x > numCols || y < 0 || y > numRows)) {
+                    // Not on this chip
+                    continue;
+                }
+
+                chipPix->data[i] = psStringCopy(chipName);
+                xPix->data.F32[i] = x;
+                yPix->data.F32[i] = y;
+
+                if (rawChip) {
+                    psString cellName = NULL; // Name of cell
+                    coordChip2Cell(&cellName, &x, &y, x, y, cellNames, cellBounds,
+                                   cellX0, cellY0, cellParityX, cellParityY, cellBinX, cellBinY);
+                    cellPix->data[i] = cellName;
+                    xCell->data.F32[i] = x;
+                    yCell->data.F32[i] = y;
+                }
+
+            }
+            psFree(pix);
+            psFree(fp);
         }
 
@@ -556,4 +632,39 @@
     }
 
+    if (fpaOut) {
+        psArray *chipPix = fpaOut->data[0]; // Chip for pixels
+        psVector *xPix = fpaOut->data[1];   // x coordinate for pixels
+        psVector *yPix = fpaOut->data[2];   // y coordinate for pixels
+        psArray *cellPix = fpaOut->data[3]; // Cell for pixels
+        psVector *xCell = fpaOut->data[4];   // x coordinate for pixels
+        psVector *yCell = fpaOut->data[5];   // y coordinate for pixels
+        psVector *fpa_x = fpas->data[0];        // FPA x coordinate
+        psVector *fpa_y = fpas->data[1];       // FPA y coordinate
+
+        for (long i = 0; i < chipPix->n; i++) {
+            const char *chipName = chipPix->data[i]; // Name of chip
+            const char *cellName = cellPix->data[i]; // Name of cell, or NULL
+            if (!data->all && (!isfinite(xPix->data.F32[i]) || !isfinite(yPix->data.F32[i]) ||
+                               !chipName || (rawFile && !cellName))) {
+                continue;
+            }
+            if (!rawFile && data->ds9) {
+                // Region file is only appropriate if we're not mapping all the way back to cell coordinates
+                fprintf(data->ds9, "image;circle(%f,%f,%f) # color=%s\n",
+                        xPix->data.F32[i], yPix->data.F32[i], data->ds9radius, data->ds9color);
+            } else if (rawFile) {
+                fprintf(stdout, "%.3f %.3f --> %.3f %.3f %s %.3f %.3f %s\n",
+                        fpa_x->data.F32[i], fpa_y->data.F32[i], xPix->data.F32[i], yPix->data.F32[i],
+                        chipName ? chipName : "UNKNOWN",
+                        xCell->data.F32[i], yCell->data.F32[i],
+                        cellName ? cellName : "UNKNOWN");
+            } else {
+                fprintf(stdout, "%.3f %.3f --> %.3f %.3f %s\n",
+                        fpa_x->data.F32[i], fpa_y->data.F32[i], xPix->data.F32[i], yPix->data.F32[i],
+                        chipName ? chipName : "UNKNOWN");
+            }
+        }
+    }
+
     if (streaksOut) {
         psArray *chipPix1 = streaksOut->data[0]; // Chip for point 1
