Index: trunk/ppTranslate/src/ppMops.h
===================================================================
--- trunk/ppTranslate/src/ppMops.h	(revision 28242)
+++ trunk/ppTranslate/src/ppMops.h	(revision 28243)
@@ -28,5 +28,6 @@
 
 typedef struct {
-    psMetadata *header;                 // FITS header
+    psString component;                 // Component name
+    psMetadata *header;                 // FITS header (extension names *.hdr)
     psString raBoresight, decBoresight; // RA,Dec of telescope boresight
     psString filter;                    // Filter for exposure
@@ -39,7 +40,10 @@
     int naxis1, naxis2;                 // Size of image
     long num;                           // Number of detections
+    psMetadata *psfHeader;              // FITS header (extension names *.psf)
     psMetadata *table;                  // Columns of data
     psVector *x, *y;                    // Image coordinates
     psVector *ra, *dec;                 // Sky coordinates
+    psMetadata *deteffHeader;           // Detection efficiency header (extension names *.deteff)
+    psMetadata *deteffTable;            // Detection efficiency table
 } ppMopsDetections;
 
Index: trunk/ppTranslate/src/ppMopsDetections.c
===================================================================
--- trunk/ppTranslate/src/ppMopsDetections.c	(revision 28242)
+++ trunk/ppTranslate/src/ppMopsDetections.c	(revision 28243)
@@ -10,4 +10,5 @@
 static void mopsDetectionsFree(ppMopsDetections *det)
 {
+    psFree(det->component);
     psFree(det->raBoresight);
     psFree(det->decBoresight);
@@ -19,4 +20,6 @@
     psFree(det->ra);
     psFree(det->dec);
+    psFree(det->deteffHeader);
+    psFree(det->deteffTable);
 
     return;
@@ -28,4 +31,5 @@
     psMemSetDeallocator(det, (psFreeFunc)mopsDetectionsFree);
 
+    det->component = NULL;
     det->raBoresight = NULL;
     det->decBoresight = NULL;
@@ -45,4 +49,6 @@
     det->ra = NULL;
     det->dec = NULL;
+    det->deteffHeader = NULL;
+    det->deteffTable = NULL;
 
     return det;
Index: trunk/ppTranslate/src/ppMopsRead.c
===================================================================
--- trunk/ppTranslate/src/ppMopsRead.c	(revision 28242)
+++ trunk/ppTranslate/src/ppMopsRead.c	(revision 28243)
@@ -4,4 +4,5 @@
 
 #include <stdio.h>
+#include <string.h>
 #include <pslib.h>
 
@@ -16,5 +17,6 @@
     psArray *detections = psArrayAlloc(num); // Array of detections, to return
     for (int i = 0; i < num; i++) {
-        psFits *fits = psFitsOpen(inNames->data[i], "r"); // FITS file
+        const char *name = inNames->data[i]; // File name
+        psFits *fits = psFitsOpen(name, "r"); // FITS file
         if (!fits) {
             psError(PS_ERR_IO, false, "Unable to open input %d", i);
@@ -41,5 +43,6 @@
             continue;
         }
-        ppMopsDetections *det = ppMopsDetectionsAlloc();
+        ppMopsDetections *det = detections->data[i] = ppMopsDetectionsAlloc();
+        det->component = psStringNCopy(name, strrchr(name, '.') - name); // Strip off extension
         det->header = header;
         det->num = size;
@@ -61,4 +64,9 @@
         det->naxis2 = psMetadataLookupS32(NULL, header, "IMNAXIS2");
 
+        det->psfHeader = psFitsReadHeader(NULL, fits);
+        if (!det->psfHeader) {
+            psError(psErrorCodeLast(), false, "Unable to read header %d", i);
+            return false;
+        }
         psMetadata *table = det->table = psFitsReadTableAllColumns(fits); // Table of interest
         if (!table) {
@@ -66,5 +74,4 @@
             return false;
         }
-        psFitsClose(fits);
 
         psVector *ra = psMetadataLookupVector(NULL, table, "RA_PSF");
@@ -80,7 +87,29 @@
         }
 
-        psTrace("ppMops.read", 2, "Read %ld rows from %s\n", det->num, (const char*)inNames->data[i]);
+        psTrace("ppMops.read", 2, "Read %ld rows from %s\n", det->num, det->component);
 
-        detections->data[i] = det;
+        if (!psFitsMoveExtName(fits, "SkyChip.deteff")) {
+            psWarning("No detection efficiencies included in %s", det->component);
+            psErrorStackPrint(stderr, "No detection efficiencies included in %s", det->component);
+            psErrorClear();
+            continue;
+        }
+
+        det->deteffHeader = psFitsReadHeader(NULL, fits);
+        if (!det->deteffHeader) {
+            psWarning("Unable to read detection efficiency header in %s", det->component);
+            psErrorClear();
+            continue;
+        }
+        det->deteffTable = psFitsReadTableAllColumns(fits);
+        if (!det->deteffTable) {
+            psFree(det->deteffHeader);
+            det->deteffHeader = NULL;
+            psWarning("Unable to read detection efficiency table in %s", det->component);
+            psErrorClear();
+            continue;
+        }
+        psTrace("ppMops.read", 2, "Read detection efficiency from %s\n", det->component);
+        psFitsClose(fits);
     }
 
Index: trunk/ppTranslate/src/ppMopsWrite.c
===================================================================
--- trunk/ppTranslate/src/ppMopsWrite.c	(revision 28242)
+++ trunk/ppTranslate/src/ppMopsWrite.c	(revision 28243)
@@ -46,8 +46,25 @@
         ppMopsDetections *det = detections->data[i]; // Detections for extension
         psTrace("ppMops.write", 1, "Writing extension %d to %s", i, args->output);
-        if (!psFitsWriteTableAllColumns(fits, det->header, det->table, NULL)) {
-            psError(psErrorCodeLast(), false, "Unable to write extension %d", i);
+        psString hdrName = NULL, psfName = NULL, deteffName = NULL;
+        psStringAppend(&hdrName, "%s.hdr", det->component);
+        psStringAppend(&psfName, "%s.psf", det->component);
+        psStringAppend(&deteffName, "%s.deteff", det->component);
+
+        if (!psFitsWriteBlank(fits, det->header, hdrName)) {
+            psError(psErrorCodeLast(), false, "Unable to write header %d", i);
             return false;
         }
+        if (!psFitsWriteTableAllColumns(fits, det->psfHeader, det->table, psfName)) {
+            psError(psErrorCodeLast(), false, "Unable to write table %d", i);
+            return false;
+        }
+        if (det->deteffHeader && det->deteffTable &&
+            !psFitsWriteTableAllColumns(fits, det->deteffHeader, det->deteffTable, deteffName)) {
+            psError(psErrorCodeLast(), false, "Unable to write detection efficiency %d", i);
+            return false;
+        }
+        psFree(hdrName);
+        psFree(psfName);
+        psFree(deteffName);
     }
     psFitsClose(fits);
