Index: trunk/psLib/src/fits/psFits.c
===================================================================
--- trunk/psLib/src/fits/psFits.c	(revision 12542)
+++ trunk/psLib/src/fits/psFits.c	(revision 12549)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.62 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-03-14 00:39:50 $
+ *  @version $Revision: 1.63 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-03-22 21:40:47 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -29,6 +29,8 @@
 #include "psTrace.h"
 #include "psVector.h"
+#include "psAbort.h"
 
 #define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
+static char *defaultExtword = "EXTNAME";
 
 static bool isHDUEmpty(const psFits* fits)
@@ -171,4 +173,5 @@
     fits->fd = fptr;
     fits->writable = (iomode == READWRITE);
+    fits->extword = NULL;
     psMemSetDeallocator(fits,(psFreeFunc)fitsFree);
 
@@ -182,5 +185,54 @@
 }
 
-
+bool psFitsSetExtnameWord (psFits *fits, const char *extword)
+{
+    PS_ASSERT_PTR_NON_NULL(fits,    false);
+    PS_ASSERT_PTR_NON_NULL(extword, false);
+
+    psFree (fits->extword);
+    fits->extword = psStringCopy (extword);
+    return true;
+}
+
+// move to the first HDU where extword == extname.  this is equivalent to fits_movnam_hdu() for
+// a user-defined word in place of EXTNAME
+bool p_psFitsMoveExtName_UserKey(const psFits *fits,
+				 const char *extname,
+				 const char *extword)
+{
+    PS_ASSERT_PTR_NON_NULL(fits,    false);
+    PS_ASSERT_PTR_NON_NULL(extname, false);
+    PS_ASSERT_PTR_NON_NULL(extword, false);
+
+    int status = 0;
+    int hdutype = 0;
+    char name[MAX_STRING_LENGTH];
+
+    // NOTE: fits_* return 0 for success
+    for (int i = 1; true; i++) {
+	// are we able to read the next HDU?
+	if (fits_movabs_hdu(fits->fd, i, &hdutype, &status)) {
+	    char fitsErr[MAX_STRING_LENGTH];
+	    fits_get_errstatus(status, fitsErr);
+	    psError(PS_ERR_LOCATION_INVALID, true,
+		    _("Could not find HDU with %s = '%s'. CFITSIO Error: %s"),
+		    extword, extname, fitsErr);
+	    return false;
+	}
+	// is there a keyword called 'extword'?
+	if (fits_read_key_str(fits->fd, (char *)extword, name, NULL, &status)) {
+	    continue;
+	}
+	// do we have the right hdu (names match)?
+	if (!strcmp (name, extname)) {
+	    return true;
+	}
+    }
+    psAbort("we should not reach here");
+}
+
+// XXX I will need to define a low-level function p_psFitsMoveExtName_UserKey () which
+// uses fits_movabs_hdu() to replicate the functionality of fits_movnam_hdu using an
+// alternate name for EXTNAME
 bool psFitsMoveExtName(const psFits* fits,
                        const char* extname)
@@ -200,4 +252,8 @@
     }
 
+    if (fits->extword != NULL) {
+	bool result = p_psFitsMoveExtName_UserKey(fits, extname, fits->extword);
+	return (result);
+    }
 
     if (fits_movnam_hdu(fits->fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
@@ -291,10 +347,10 @@
     char name[MAX_STRING_LENGTH];
 
-    if (fits_read_key_str(fits->fd, "EXTNAME", name, NULL, &status) != 0) {
-        status = 0;
-        if (fits_read_key_str(fits->fd, "HDUNAME", name, NULL, &status) != 0) {
-            int num = psFitsGetExtNum(fits);
-            snprintf(name, MAX_STRING_LENGTH, "EXT-%3d",num);
-        }
+    char *extword = (fits->extword == NULL) ? defaultExtword : fits->extword;
+
+    if (fits_read_key_str(fits->fd, extword, name, NULL, &status) != 0) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                _("Header keyword %s is not found"), extword);
+	return NULL;
     }
     return psStringCopy(name);
@@ -317,5 +373,7 @@
     int status = 0;
 
-    if (fits_update_key_str(fits->fd, "EXTNAME", (char*)name, NULL, &status) != 0) {
+    char *extword = (fits->extword == NULL) ? defaultExtword : fits->extword;
+
+    if (fits_update_key_str(fits->fd, extword, (char*)name, NULL, &status) != 0) {
         char fitsErr[MAX_STRING_LENGTH];
         (void)fits_get_errstatus(status, fitsErr);
Index: trunk/psLib/src/fits/psFits.h
===================================================================
--- trunk/psLib/src/fits/psFits.h	(revision 12542)
+++ trunk/psLib/src/fits/psFits.h	(revision 12549)
@@ -4,6 +4,6 @@
  * @author Robert DeSonia, MHPCC
  *
- * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
- * @date $Date: 2007-01-23 22:47:23 $
+ * @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2007-03-22 21:40:47 $
  * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
  */
@@ -43,6 +43,7 @@
 typedef struct
 {
-    fitsfile* fd;                      ///< the CFITSIO fits files handle.
-    bool writable;                     ///< Is the file writable?
+    fitsfile* fd;			///< the CFITSIO fits files handle.
+    bool writable;			///< Is the file writable?
+    char *extword;			///< user-specified word to name extensions (NULL implies EXTNAME)
 }
 psFits;
@@ -84,4 +85,9 @@
 );
 
+// move to the first HDU where extword == extname.  this is equivalent to fits_movnam_hdu() for
+// a user-defined word in place of EXTNAME
+bool p_psFitsMoveExtName_UserKey(const psFits *fits,
+				 const char *extname,
+				 const char *extword);
 
 /** Moves the FITS HDU to the specified extension name.
Index: trunk/psLib/src/fits/psFitsTable.c
===================================================================
--- trunk/psLib/src/fits/psFitsTable.c	(revision 12542)
+++ trunk/psLib/src/fits/psFitsTable.c	(revision 12549)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-03-14 00:39:50 $
+ *  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-03-22 21:40:47 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -585,5 +585,5 @@
                         (char**)columnTypes->data, // format of the columns
                         NULL, // physical unit of columns
-                        (char*)extname, // extension name; casting away const because cfitsio is horrible
+                        NULL, // skip extension name: we set the by hand below
                         &status);
     } else {
@@ -605,5 +605,5 @@
                          (char**)columnTypes->data, // format of the columns
                          NULL, // physical unit of columns
-                         (char*)extname, // extension name; casting away const because cfitsio is horrible
+                         NULL, // skip extension name: we set this by hand below
                          0, &status);
     }
@@ -629,4 +629,13 @@
     }
 
+    // write the header, if any.
+    if (extname && strlen(extname) > 0) {
+        if (!psFitsSetExtName(fits, extname)) {
+	    psError(PS_ERR_IO, false, "Unable to write FITS header extension name.\n");
+	    psFree(colSpecsIter);
+	    psFree(colSpecs);
+	    return false;
+	}
+    }
 
     // cfitsio requires that we write the data by columns --- urgh!
