Index: /trunk/psLib/psLib.kdevses
===================================================================
--- /trunk/psLib/psLib.kdevses	(revision 2961)
+++ /trunk/psLib/psLib.kdevses	(revision 2962)
@@ -2,5 +2,15 @@
 <!DOCTYPE KDevPrjSession>
 <KDevPrjSession>
- <DocsAndViews NumberOfDocuments="0" />
+ <DocsAndViews NumberOfDocuments="3" >
+  <Doc0 NumberOfViews="1" URL="file:/home/desonia/psLib/test/fileUtils/tst_psFits.c" >
+   <View0 Type="Source" />
+  </Doc0>
+  <Doc1 NumberOfViews="1" URL="file:/home/desonia/psLib/src/fileUtils/psFits.h" >
+   <View0 Type="Source" />
+  </Doc1>
+  <Doc2 NumberOfViews="1" URL="file:/home/desonia/psLib/src/fileUtils/psFits.c" >
+   <View0 line="318" Type="Source" />
+  </Doc2>
+ </DocsAndViews>
  <pluginList>
   <kdevbookmarks>
@@ -11,7 +21,4 @@
    </bookmarks>
   </kdevbookmarks>
-  <kdevsubversion>
-   <subversion recurseresolve="1" recurserelocate="1" recursemerge="1" recursecommit="1" base="" recursepropget="1" recurseswitch="1" recurseupdate="1" recursepropset="1" recursediff="1" recurserevert="1" forcemove="1" recursecheckout="1" forceremove="1" recurseadd="1" recurseproplist="1" forcemerge="1" />
-  </kdevsubversion>
   <kdevvalgrind>
    <executable path="" params="" />
Index: /trunk/psLib/src/dataIO/Makefile
===================================================================
--- /trunk/psLib/src/dataIO/Makefile	(revision 2961)
+++ /trunk/psLib/src/dataIO/Makefile	(revision 2962)
@@ -8,5 +8,6 @@
     -I.. -I../image -I../astronomy -DSER7_FILE="\"$(SER7_FILE)\"" -DTAIUTC_FILE="\"$(TAIUTC_FILE)\""
 
-SRC_OBJS = psLookupTable.o
+SRC_OBJS = psLookupTable.o \
+	psFits.o
 
 OBJS = $(addprefix makedir/,$(SRC_OBJS))
Index: /trunk/psLib/src/dataIO/psFileUtilsErrors.dat
===================================================================
--- /trunk/psLib/src/dataIO/psFileUtilsErrors.dat	(revision 2961)
+++ /trunk/psLib/src/dataIO/psFileUtilsErrors.dat	(revision 2962)
@@ -10,5 +10,5 @@
 psLookupTable_PARSE_VALUE              Unable to parse string, %s on line %lld.
 psLookupTable_PARSE_TYPE               Unable to parse type, %s on line %lld.
-psLookupTable_PARSE_GENERAL            Unable to read lookup table item, %s on line %lld 
+psLookupTable_PARSE_GENERAL            Unable to read lookup table item, %s on line %lld
 psLookupTable_INTERPOLATE_HIGH         High index too big, %d.
 psLookupTable_INTERPOLATE_LOW          Low index too small, %d.
@@ -19,4 +19,5 @@
 psFits_FILENAME_INVALID                Could not open file,'%s'.\nCFITSIO Error: %s
 psFits_FILENAME_NULL                   Specified filename can not be NULL.
+psFits_EXTNAME_NULL                    Specified extension name can not be NULL.
 psFits_EXTNAME_INVALID                 Could not find HDU '%s' in file %s.\nCFITSIO Error: %s
 psFits_EXTNUM_INVALID                  Could not find HDU #%d in file %s.\nCFITSIO Error: %s
@@ -40,8 +41,14 @@
 psFits_METADATA_NULL                   The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed.
 psFits_METADATA_PTYPE_UNSUPPORTED      A metadata item's primative type, %d, is not supported.
-psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows.  
+psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows.
 psFits_GET_TABLE_ELEMENT               Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s
 psFits_FIND_COLUMN                     Specified column, %s, was not found.\nCFITSIO Error: %s
 psFits_GET_COLTYPE                     Could not determine the datatype of the table column.\nCFITSIO Error: %s
 psFits_TABLE_READ_COL                  Failed to read table column.\nCFITSIO Error: %s
+psFits_DATATYPE_UNKNOWN                Could not determine image data type.\nCFITSIO Error: %s
+psFits_IMAGE_DIM_UNKNOWN               Could not determine image dimensions.\nCFITSIO Error: %s
+psFits_IMAGE_DIMENSION_UNSUPPORTED     Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O.
+psFits_IMAGE_SIZE_UNKNOWN              Could not determine image size.\nCFITSIO Error: %s
+psFits_FITS_TYPE_UNSUPPORTED           FITS image type, BITPIX=%d, is not supported.
+psFits_READ_FAILED                     Reading FITS file failed.\nCFITSIO Error: %s
 #
Index: /trunk/psLib/src/dataIO/psFileUtilsErrors.h
===================================================================
--- /trunk/psLib/src/dataIO/psFileUtilsErrors.h	(revision 2961)
+++ /trunk/psLib/src/dataIO/psFileUtilsErrors.h	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -33,5 +33,5 @@
 #define PS_ERRORTEXT_psLookupTable_PARSE_VALUE "Unable to parse string, %s on line %lld."
 #define PS_ERRORTEXT_psLookupTable_PARSE_TYPE "Unable to parse type, %s on line %lld."
-#define PS_ERRORTEXT_psLookupTable_PARSE_GENERAL "Unable to read lookup table item, %s on line %lld "
+#define PS_ERRORTEXT_psLookupTable_PARSE_GENERAL "Unable to read lookup table item, %s on line %lld"
 #define PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH "High index too big, %d."
 #define PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW "Low index too small, %d."
@@ -41,4 +41,5 @@
 #define PS_ERRORTEXT_psFits_FILENAME_INVALID "Could not open file,'%s'.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_FILENAME_NULL "Specified filename can not be NULL."
+#define PS_ERRORTEXT_psFits_EXTNAME_NULL "Specified extension name can not be NULL."
 #define PS_ERRORTEXT_psFits_EXTNAME_INVALID "Could not find HDU '%s' in file %s.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_EXTNUM_INVALID "Could not find HDU #%d in file %s.\nCFITSIO Error: %s"
@@ -62,9 +63,15 @@
 #define PS_ERRORTEXT_psFits_METADATA_NULL "The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed."
 #define PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED "A metadata item's primative type, %d, is not supported."
-#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows.  "
+#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows."
 #define PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT "Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_FIND_COLUMN "Specified column, %s, was not found.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_GET_COLTYPE "Could not determine the datatype of the table column.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_TABLE_READ_COL "Failed to read table column.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN "Could not determine image data type.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN "Could not determine image dimensions.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED "Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O."
+#define PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN "Could not determine image size.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED "FITS image type, BITPIX=%d, is not supported."
+#define PS_ERRORTEXT_psFits_READ_FAILED "Reading FITS file failed.\nCFITSIO Error: %s"
 //~End
 
Index: /trunk/psLib/src/dataIO/psFits.c
===================================================================
--- /trunk/psLib/src/dataIO/psFits.c	(revision 2961)
+++ /trunk/psLib/src/dataIO/psFits.c	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -196,6 +196,5 @@
 }
 
-psFits* psFitsAlloc(const char* name,                  ///< the FITS file name
-                    bool readwrite)                    ///< if TRUE, the file is open for read/write.
+psFits* psFitsAlloc(const char* name)
 {
     int status = 0;
@@ -207,10 +206,12 @@
         return NULL;
     }
-
-    int iomode = (readwrite) ? READWRITE : READONLY;
 
     /* Open/Create the FITS file */
     if (access(name, F_OK) == 0) {     // file exists
-        (void)fits_open_file(&fptr, name, iomode, &status);
+        (void)fits_open_file(&fptr, name, READWRITE, &status);
+        if (fptr == NULL) { // if failed, try openning as just read-only
+            status = 0;
+            (void)fits_open_file(&fptr, name, READONLY, &status);
+        }
         if (fptr == NULL || status != 0) {
             char fitsErr[MAX_STRING_LENGTH];
@@ -221,5 +222,5 @@
             return NULL;
         }
-    } else {  // file does not exist
+    } else {  // file does not exist, so create.
         (void)fits_create_file(&fptr, name, &status);
         if (fptr == NULL || status != 0) {
@@ -253,4 +254,10 @@
     }
 
+    if (extname == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
 
     if (fits_movnam_hdu(fits->p_fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
@@ -317,5 +324,5 @@
     }
 
-    return hdutype-1;
+    return hdutype;
 }
 
@@ -339,4 +346,32 @@
     }
     return psStringCopy(name);
+}
+
+bool psFitsSetExtName(psFits* fits, const char* name)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    if (fits_update_key_str(fits->p_fd, "EXTNAME", (char*)name, NULL, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
 }
 
@@ -540,4 +575,181 @@
 }
 
+psImage* psFitsReadImage(psImage* output, // a psImage to recycle.
+                         psFits* fits,    // the psFits object
+                         psRegion region, // the region in the FITS image to read
+                         int z)           // the z-plane in the FITS image cube to read
+{
+    psS32 status = 0;           /* CFITSIO file vars */
+    psS32 nAxis = 0;
+    psS32 anynull = 0;
+    psS32 bitPix = 0;           /* Pixel type */
+    long nAxes[3];
+    long firstPixel[3];         /* lower-left corner of image subset */
+    long lastPixel[3];          /* upper-right corner of image subset */
+    long increment[3];          /* increment for image subset */
+    char fitsErr[80] = "";      /* CFITSIO error message string */
+    psS32 fitsDatatype = 0;
+    psS32 datatype = 0;
+
+    if (fits == NULL)
+    {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0)
+    {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU)
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fits->p_fd, &bitPix, &status) != 0)
+    {
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fits->p_fd, &nAxis, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ((nAxis < 2) || (nAxis > 3))
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED,
+                nAxis);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file */
+    if (fits_get_img_size(fits->p_fd, nAxis, nAxes, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0)
+    {
+        lastPixel[0] = region.x1;
+    } else
+    {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0)
+    {
+        lastPixel[1] = region.y1;
+    } else
+    {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    lastPixel[2] = z + 1;
+
+    increment[0] = 1;
+    increment[1] = 1;
+    increment[2] = 1;
+
+    switch (bitPix)
+    {
+    case BYTE_IMG:
+        datatype = PS_TYPE_U8;
+        fitsDatatype = TBYTE;
+        break;
+    case SBYTE_IMG:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        datatype = PS_TYPE_S64;
+        fitsDatatype = TLONGLONG;
+        break;
+    case FLOAT_IMG:
+        datatype = PS_TYPE_F32;
+        fitsDatatype = TFLOAT;
+        break;
+    case DOUBLE_IMG:
+        datatype = PS_TYPE_F64;
+        fitsDatatype = TDOUBLE;
+        break;
+    default:
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED,
+                bitPix);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output,
+                            lastPixel[0]-firstPixel[0]+1,
+                            lastPixel[1]-firstPixel[1]+1,
+                            datatype);
+
+    // n.b., this assumes contiguous image buffer
+    if (fits_read_subset(fits->p_fd, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0)
+    {
+        psFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_READ_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    return output;
+
+}
+
 bool psFitsWriteImage(psFits* fits,
                       const psMetadata* header,
@@ -594,14 +806,13 @@
     }
 
-    long firstPixel = (numZPlanes-1)*numRows*numCols; // start write in last z-plane
-
     if (input->parent == NULL) { // if no parent, assume that the image data is contiguous
         fits_write_img(fits->p_fd,
                        dataType,              // datatype
-                       firstPixel,                     // writing to the first z-plane
+                       1,                     // writing to the first z-plane
                        numCols*numRows,       // number of elements to write, i.e., the whole image
                        input->data.V[0],      // the data
                        &status);
     } else { // image data may not be contiguous; write one row at a time
+        int firstPixel = 1;
         for (int row = 0; row < numRows; row++) {
             fits_write_img(fits->p_fd,
Index: /trunk/psLib/src/dataIO/psFits.h
===================================================================
--- /trunk/psLib/src/dataIO/psFits.h	(revision 2961)
+++ /trunk/psLib/src/dataIO/psFits.h	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -37,5 +37,5 @@
 
 /** FITS file object.
- * 
+ *
  *  This object should be considered opaque to the user; no item in this
  *  struct should be accessed directly.
@@ -51,10 +51,9 @@
 /** Opens a FITS file and allocates the associated psFits object.
  *
- *  @return psFits*    new psFits object for the FITS files specified or 
+ *  @return psFits*    new psFits object for the FITS files specified or
  *                     NULL if the open of the FITS file failed
  */
 psFits* psFitsAlloc(
-    const char* name,                  ///< the FITS file name
-    bool readwrite                     ///< if TRUE, the file is open for read/write.
+    const char* name                   ///< the FITS file name
 );
 
@@ -89,5 +88,5 @@
 /** Get the current extension name.
  *
- *  @return int        Current HDU name of the psFits file or NULL if an 
+ *  @return int        Current HDU name of the psFits file or NULL if an
  *                     error occurred.
  */
@@ -96,7 +95,16 @@
 );
 
+/** Set the current extension's name
+ *
+ *  @return bool       TRUE if the extension was successfully set, otherwise FALSE.
+ */
+bool psFitsSetExtName(
+    psFits* fits,                      ///< the psFits object
+    const char* name                   ///< the extension name
+);
+
 /** Get the total number of HDUs in the FITS file.
  *
- *  @return int        The total number of HDUs in the FITS file or < 0 if an 
+ *  @return int        The total number of HDUs in the FITS file or < 0 if an
  *                     error occurred.
  */
@@ -107,5 +115,5 @@
 /** Get the extension type of the current HDU.
  *
- *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN, 
+ *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN,
  *                     the type could not be determined.
  */
@@ -151,5 +159,5 @@
  *  @return psImage*     the read image or NULL if there was an error.
  */
-psImage* psFitsReadImageSection(
+psImage* psFitsReadImage(
     psImage* out,                      ///< a psImage to recycle.
     psFits* fits,                      ///< the psFits object
@@ -182,5 +190,5 @@
  *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
  *
- *  @return psArray*    Array of data items for the specified column or NULL 
+ *  @return psArray*    Array of data items for the specified column or NULL
  *                      if an error occurred.
  */
@@ -207,5 +215,5 @@
  *  @return psArray*     Array of psMetadata items, which contains the output
  *                       data items of each row.
- *  
+ *
  *  @see psFitsReadTableRow
  */
@@ -218,5 +226,5 @@
  *
  *  @return bool        TRUE if the write was successful, otherwise FALSE
- *  
+ *
  *  @see psFitsReadTableRow
  */
Index: /trunk/psLib/src/dataManip/psMatrixVectorArithmetic.c
===================================================================
--- /trunk/psLib/src/dataManip/psMatrixVectorArithmetic.c	(revision 2961)
+++ /trunk/psLib/src/dataManip/psMatrixVectorArithmetic.c	(revision 2962)
@@ -29,6 +29,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-11 03:06:31 $
+ *  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -377,5 +377,7 @@
 // Preprocessor macro function to create arithmetic function operation name
 #define BINARY_OP(DIM1,DIM2,OUT,IN1,OP,IN2)                                                                  \
-if(!strncmp(OP, "+", 1)) {                                                                                   \
+if(!strncmp(OP, "=", 1)) {                                                                                   \
+    BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i2,IN2);                                                                  \
+} else if(!strncmp(OP, "+", 1)) {                                                                            \
     BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 + *i2,IN2);                                                            \
 } else if(!strncmp(OP, "-", 1)) {                                                                            \
@@ -384,5 +386,5 @@
     BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 * *i2,IN2);                                                            \
 } else if(!strncmp(OP, "/", 1)) {                                                                            \
-    BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 / *i2,IN2);                                                    \
+    BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 / *i2,IN2);                                                            \
 } else if(!strncmp(OP, "^", 1)) {                                                                            \
     if(PS_IS_PSELEMTYPE_COMPLEX(IN1->type)) {                                                                \
Index: /trunk/psLib/src/dataManip/psMatrixVectorArithmetic.h
===================================================================
--- /trunk/psLib/src/dataManip/psMatrixVectorArithmetic.h	(revision 2961)
+++ /trunk/psLib/src/dataManip/psMatrixVectorArithmetic.h	(revision 2962)
@@ -30,6 +30,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-10-27 00:57:31 $
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -49,7 +49,7 @@
  *      out = in1 op in2,
  *
- *      Where op is: "+", "-", "*", "/", "^", "min", or "max"
+ *      Where op is: "=", "+", "-", "*", "/", "^", "min", or "max"
  *
- *  This function only supports vector-vector or image-image opertions.
+ *  This function only supports vector-vector or image-image operations.
  *
  *  @return  psType* : Pointer to either psImage or psVector.
Index: /trunk/psLib/src/fileUtils/Makefile
===================================================================
--- /trunk/psLib/src/fileUtils/Makefile	(revision 2961)
+++ /trunk/psLib/src/fileUtils/Makefile	(revision 2962)
@@ -8,5 +8,6 @@
     -I.. -I../image -I../astronomy -DSER7_FILE="\"$(SER7_FILE)\"" -DTAIUTC_FILE="\"$(TAIUTC_FILE)\""
 
-SRC_OBJS = psLookupTable.o
+SRC_OBJS = psLookupTable.o \
+	psFits.o
 
 OBJS = $(addprefix makedir/,$(SRC_OBJS))
Index: /trunk/psLib/src/fileUtils/psFileUtilsErrors.dat
===================================================================
--- /trunk/psLib/src/fileUtils/psFileUtilsErrors.dat	(revision 2961)
+++ /trunk/psLib/src/fileUtils/psFileUtilsErrors.dat	(revision 2962)
@@ -10,5 +10,5 @@
 psLookupTable_PARSE_VALUE              Unable to parse string, %s on line %lld.
 psLookupTable_PARSE_TYPE               Unable to parse type, %s on line %lld.
-psLookupTable_PARSE_GENERAL            Unable to read lookup table item, %s on line %lld 
+psLookupTable_PARSE_GENERAL            Unable to read lookup table item, %s on line %lld
 psLookupTable_INTERPOLATE_HIGH         High index too big, %d.
 psLookupTable_INTERPOLATE_LOW          Low index too small, %d.
@@ -19,4 +19,5 @@
 psFits_FILENAME_INVALID                Could not open file,'%s'.\nCFITSIO Error: %s
 psFits_FILENAME_NULL                   Specified filename can not be NULL.
+psFits_EXTNAME_NULL                    Specified extension name can not be NULL.
 psFits_EXTNAME_INVALID                 Could not find HDU '%s' in file %s.\nCFITSIO Error: %s
 psFits_EXTNUM_INVALID                  Could not find HDU #%d in file %s.\nCFITSIO Error: %s
@@ -40,8 +41,14 @@
 psFits_METADATA_NULL                   The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed.
 psFits_METADATA_PTYPE_UNSUPPORTED      A metadata item's primative type, %d, is not supported.
-psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows.  
+psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows.
 psFits_GET_TABLE_ELEMENT               Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s
 psFits_FIND_COLUMN                     Specified column, %s, was not found.\nCFITSIO Error: %s
 psFits_GET_COLTYPE                     Could not determine the datatype of the table column.\nCFITSIO Error: %s
 psFits_TABLE_READ_COL                  Failed to read table column.\nCFITSIO Error: %s
+psFits_DATATYPE_UNKNOWN                Could not determine image data type.\nCFITSIO Error: %s
+psFits_IMAGE_DIM_UNKNOWN               Could not determine image dimensions.\nCFITSIO Error: %s
+psFits_IMAGE_DIMENSION_UNSUPPORTED     Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O.
+psFits_IMAGE_SIZE_UNKNOWN              Could not determine image size.\nCFITSIO Error: %s
+psFits_FITS_TYPE_UNSUPPORTED           FITS image type, BITPIX=%d, is not supported.
+psFits_READ_FAILED                     Reading FITS file failed.\nCFITSIO Error: %s
 #
Index: /trunk/psLib/src/fileUtils/psFileUtilsErrors.h
===================================================================
--- /trunk/psLib/src/fileUtils/psFileUtilsErrors.h	(revision 2961)
+++ /trunk/psLib/src/fileUtils/psFileUtilsErrors.h	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -33,5 +33,5 @@
 #define PS_ERRORTEXT_psLookupTable_PARSE_VALUE "Unable to parse string, %s on line %lld."
 #define PS_ERRORTEXT_psLookupTable_PARSE_TYPE "Unable to parse type, %s on line %lld."
-#define PS_ERRORTEXT_psLookupTable_PARSE_GENERAL "Unable to read lookup table item, %s on line %lld "
+#define PS_ERRORTEXT_psLookupTable_PARSE_GENERAL "Unable to read lookup table item, %s on line %lld"
 #define PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH "High index too big, %d."
 #define PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW "Low index too small, %d."
@@ -41,4 +41,5 @@
 #define PS_ERRORTEXT_psFits_FILENAME_INVALID "Could not open file,'%s'.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_FILENAME_NULL "Specified filename can not be NULL."
+#define PS_ERRORTEXT_psFits_EXTNAME_NULL "Specified extension name can not be NULL."
 #define PS_ERRORTEXT_psFits_EXTNAME_INVALID "Could not find HDU '%s' in file %s.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_EXTNUM_INVALID "Could not find HDU #%d in file %s.\nCFITSIO Error: %s"
@@ -62,9 +63,15 @@
 #define PS_ERRORTEXT_psFits_METADATA_NULL "The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed."
 #define PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED "A metadata item's primative type, %d, is not supported."
-#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows.  "
+#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows."
 #define PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT "Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_FIND_COLUMN "Specified column, %s, was not found.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_GET_COLTYPE "Could not determine the datatype of the table column.\nCFITSIO Error: %s"
 #define PS_ERRORTEXT_psFits_TABLE_READ_COL "Failed to read table column.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN "Could not determine image data type.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN "Could not determine image dimensions.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED "Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O."
+#define PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN "Could not determine image size.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED "FITS image type, BITPIX=%d, is not supported."
+#define PS_ERRORTEXT_psFits_READ_FAILED "Reading FITS file failed.\nCFITSIO Error: %s"
 //~End
 
Index: /trunk/psLib/src/fileUtils/psFits.c
===================================================================
--- /trunk/psLib/src/fileUtils/psFits.c	(revision 2961)
+++ /trunk/psLib/src/fileUtils/psFits.c	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -196,6 +196,5 @@
 }
 
-psFits* psFitsAlloc(const char* name,                  ///< the FITS file name
-                    bool readwrite)                    ///< if TRUE, the file is open for read/write.
+psFits* psFitsAlloc(const char* name)
 {
     int status = 0;
@@ -207,10 +206,12 @@
         return NULL;
     }
-
-    int iomode = (readwrite) ? READWRITE : READONLY;
 
     /* Open/Create the FITS file */
     if (access(name, F_OK) == 0) {     // file exists
-        (void)fits_open_file(&fptr, name, iomode, &status);
+        (void)fits_open_file(&fptr, name, READWRITE, &status);
+        if (fptr == NULL) { // if failed, try openning as just read-only
+            status = 0;
+            (void)fits_open_file(&fptr, name, READONLY, &status);
+        }
         if (fptr == NULL || status != 0) {
             char fitsErr[MAX_STRING_LENGTH];
@@ -221,5 +222,5 @@
             return NULL;
         }
-    } else {  // file does not exist
+    } else {  // file does not exist, so create.
         (void)fits_create_file(&fptr, name, &status);
         if (fptr == NULL || status != 0) {
@@ -253,4 +254,10 @@
     }
 
+    if (extname == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
 
     if (fits_movnam_hdu(fits->p_fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
@@ -317,5 +324,5 @@
     }
 
-    return hdutype-1;
+    return hdutype;
 }
 
@@ -339,4 +346,32 @@
     }
     return psStringCopy(name);
+}
+
+bool psFitsSetExtName(psFits* fits, const char* name)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    if (fits_update_key_str(fits->p_fd, "EXTNAME", (char*)name, NULL, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
 }
 
@@ -540,4 +575,181 @@
 }
 
+psImage* psFitsReadImage(psImage* output, // a psImage to recycle.
+                         psFits* fits,    // the psFits object
+                         psRegion region, // the region in the FITS image to read
+                         int z)           // the z-plane in the FITS image cube to read
+{
+    psS32 status = 0;           /* CFITSIO file vars */
+    psS32 nAxis = 0;
+    psS32 anynull = 0;
+    psS32 bitPix = 0;           /* Pixel type */
+    long nAxes[3];
+    long firstPixel[3];         /* lower-left corner of image subset */
+    long lastPixel[3];          /* upper-right corner of image subset */
+    long increment[3];          /* increment for image subset */
+    char fitsErr[80] = "";      /* CFITSIO error message string */
+    psS32 fitsDatatype = 0;
+    psS32 datatype = 0;
+
+    if (fits == NULL)
+    {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0)
+    {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU)
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fits->p_fd, &bitPix, &status) != 0)
+    {
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fits->p_fd, &nAxis, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ((nAxis < 2) || (nAxis > 3))
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED,
+                nAxis);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file */
+    if (fits_get_img_size(fits->p_fd, nAxis, nAxes, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0)
+    {
+        lastPixel[0] = region.x1;
+    } else
+    {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0)
+    {
+        lastPixel[1] = region.y1;
+    } else
+    {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    lastPixel[2] = z + 1;
+
+    increment[0] = 1;
+    increment[1] = 1;
+    increment[2] = 1;
+
+    switch (bitPix)
+    {
+    case BYTE_IMG:
+        datatype = PS_TYPE_U8;
+        fitsDatatype = TBYTE;
+        break;
+    case SBYTE_IMG:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        datatype = PS_TYPE_S64;
+        fitsDatatype = TLONGLONG;
+        break;
+    case FLOAT_IMG:
+        datatype = PS_TYPE_F32;
+        fitsDatatype = TFLOAT;
+        break;
+    case DOUBLE_IMG:
+        datatype = PS_TYPE_F64;
+        fitsDatatype = TDOUBLE;
+        break;
+    default:
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED,
+                bitPix);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output,
+                            lastPixel[0]-firstPixel[0]+1,
+                            lastPixel[1]-firstPixel[1]+1,
+                            datatype);
+
+    // n.b., this assumes contiguous image buffer
+    if (fits_read_subset(fits->p_fd, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0)
+    {
+        psFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_READ_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    return output;
+
+}
+
 bool psFitsWriteImage(psFits* fits,
                       const psMetadata* header,
@@ -594,14 +806,13 @@
     }
 
-    long firstPixel = (numZPlanes-1)*numRows*numCols; // start write in last z-plane
-
     if (input->parent == NULL) { // if no parent, assume that the image data is contiguous
         fits_write_img(fits->p_fd,
                        dataType,              // datatype
-                       firstPixel,                     // writing to the first z-plane
+                       1,                     // writing to the first z-plane
                        numCols*numRows,       // number of elements to write, i.e., the whole image
                        input->data.V[0],      // the data
                        &status);
     } else { // image data may not be contiguous; write one row at a time
+        int firstPixel = 1;
         for (int row = 0; row < numRows; row++) {
             fits_write_img(fits->p_fd,
Index: /trunk/psLib/src/fileUtils/psFits.h
===================================================================
--- /trunk/psLib/src/fileUtils/psFits.h	(revision 2961)
+++ /trunk/psLib/src/fileUtils/psFits.h	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -37,5 +37,5 @@
 
 /** FITS file object.
- * 
+ *
  *  This object should be considered opaque to the user; no item in this
  *  struct should be accessed directly.
@@ -51,10 +51,9 @@
 /** Opens a FITS file and allocates the associated psFits object.
  *
- *  @return psFits*    new psFits object for the FITS files specified or 
+ *  @return psFits*    new psFits object for the FITS files specified or
  *                     NULL if the open of the FITS file failed
  */
 psFits* psFitsAlloc(
-    const char* name,                  ///< the FITS file name
-    bool readwrite                     ///< if TRUE, the file is open for read/write.
+    const char* name                   ///< the FITS file name
 );
 
@@ -89,5 +88,5 @@
 /** Get the current extension name.
  *
- *  @return int        Current HDU name of the psFits file or NULL if an 
+ *  @return int        Current HDU name of the psFits file or NULL if an
  *                     error occurred.
  */
@@ -96,7 +95,16 @@
 );
 
+/** Set the current extension's name
+ *
+ *  @return bool       TRUE if the extension was successfully set, otherwise FALSE.
+ */
+bool psFitsSetExtName(
+    psFits* fits,                      ///< the psFits object
+    const char* name                   ///< the extension name
+);
+
 /** Get the total number of HDUs in the FITS file.
  *
- *  @return int        The total number of HDUs in the FITS file or < 0 if an 
+ *  @return int        The total number of HDUs in the FITS file or < 0 if an
  *                     error occurred.
  */
@@ -107,5 +115,5 @@
 /** Get the extension type of the current HDU.
  *
- *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN, 
+ *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN,
  *                     the type could not be determined.
  */
@@ -151,5 +159,5 @@
  *  @return psImage*     the read image or NULL if there was an error.
  */
-psImage* psFitsReadImageSection(
+psImage* psFitsReadImage(
     psImage* out,                      ///< a psImage to recycle.
     psFits* fits,                      ///< the psFits object
@@ -182,5 +190,5 @@
  *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
  *
- *  @return psArray*    Array of data items for the specified column or NULL 
+ *  @return psArray*    Array of data items for the specified column or NULL
  *                      if an error occurred.
  */
@@ -207,5 +215,5 @@
  *  @return psArray*     Array of psMetadata items, which contains the output
  *                       data items of each row.
- *  
+ *
  *  @see psFitsReadTableRow
  */
@@ -218,5 +226,5 @@
  *
  *  @return bool        TRUE if the write was successful, otherwise FALSE
- *  
+ *
  *  @see psFitsReadTableRow
  */
Index: /trunk/psLib/src/fits/psFits.c
===================================================================
--- /trunk/psLib/src/fits/psFits.c	(revision 2961)
+++ /trunk/psLib/src/fits/psFits.c	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -196,6 +196,5 @@
 }
 
-psFits* psFitsAlloc(const char* name,                  ///< the FITS file name
-                    bool readwrite)                    ///< if TRUE, the file is open for read/write.
+psFits* psFitsAlloc(const char* name)
 {
     int status = 0;
@@ -207,10 +206,12 @@
         return NULL;
     }
-
-    int iomode = (readwrite) ? READWRITE : READONLY;
 
     /* Open/Create the FITS file */
     if (access(name, F_OK) == 0) {     // file exists
-        (void)fits_open_file(&fptr, name, iomode, &status);
+        (void)fits_open_file(&fptr, name, READWRITE, &status);
+        if (fptr == NULL) { // if failed, try openning as just read-only
+            status = 0;
+            (void)fits_open_file(&fptr, name, READONLY, &status);
+        }
         if (fptr == NULL || status != 0) {
             char fitsErr[MAX_STRING_LENGTH];
@@ -221,5 +222,5 @@
             return NULL;
         }
-    } else {  // file does not exist
+    } else {  // file does not exist, so create.
         (void)fits_create_file(&fptr, name, &status);
         if (fptr == NULL || status != 0) {
@@ -253,4 +254,10 @@
     }
 
+    if (extname == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
 
     if (fits_movnam_hdu(fits->p_fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
@@ -317,5 +324,5 @@
     }
 
-    return hdutype-1;
+    return hdutype;
 }
 
@@ -339,4 +346,32 @@
     }
     return psStringCopy(name);
+}
+
+bool psFitsSetExtName(psFits* fits, const char* name)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    if (fits_update_key_str(fits->p_fd, "EXTNAME", (char*)name, NULL, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
 }
 
@@ -540,4 +575,181 @@
 }
 
+psImage* psFitsReadImage(psImage* output, // a psImage to recycle.
+                         psFits* fits,    // the psFits object
+                         psRegion region, // the region in the FITS image to read
+                         int z)           // the z-plane in the FITS image cube to read
+{
+    psS32 status = 0;           /* CFITSIO file vars */
+    psS32 nAxis = 0;
+    psS32 anynull = 0;
+    psS32 bitPix = 0;           /* Pixel type */
+    long nAxes[3];
+    long firstPixel[3];         /* lower-left corner of image subset */
+    long lastPixel[3];          /* upper-right corner of image subset */
+    long increment[3];          /* increment for image subset */
+    char fitsErr[80] = "";      /* CFITSIO error message string */
+    psS32 fitsDatatype = 0;
+    psS32 datatype = 0;
+
+    if (fits == NULL)
+    {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0)
+    {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU)
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fits->p_fd, &bitPix, &status) != 0)
+    {
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fits->p_fd, &nAxis, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ((nAxis < 2) || (nAxis > 3))
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED,
+                nAxis);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file */
+    if (fits_get_img_size(fits->p_fd, nAxis, nAxes, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0)
+    {
+        lastPixel[0] = region.x1;
+    } else
+    {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0)
+    {
+        lastPixel[1] = region.y1;
+    } else
+    {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    lastPixel[2] = z + 1;
+
+    increment[0] = 1;
+    increment[1] = 1;
+    increment[2] = 1;
+
+    switch (bitPix)
+    {
+    case BYTE_IMG:
+        datatype = PS_TYPE_U8;
+        fitsDatatype = TBYTE;
+        break;
+    case SBYTE_IMG:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        datatype = PS_TYPE_S64;
+        fitsDatatype = TLONGLONG;
+        break;
+    case FLOAT_IMG:
+        datatype = PS_TYPE_F32;
+        fitsDatatype = TFLOAT;
+        break;
+    case DOUBLE_IMG:
+        datatype = PS_TYPE_F64;
+        fitsDatatype = TDOUBLE;
+        break;
+    default:
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED,
+                bitPix);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output,
+                            lastPixel[0]-firstPixel[0]+1,
+                            lastPixel[1]-firstPixel[1]+1,
+                            datatype);
+
+    // n.b., this assumes contiguous image buffer
+    if (fits_read_subset(fits->p_fd, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0)
+    {
+        psFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_READ_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    return output;
+
+}
+
 bool psFitsWriteImage(psFits* fits,
                       const psMetadata* header,
@@ -594,14 +806,13 @@
     }
 
-    long firstPixel = (numZPlanes-1)*numRows*numCols; // start write in last z-plane
-
     if (input->parent == NULL) { // if no parent, assume that the image data is contiguous
         fits_write_img(fits->p_fd,
                        dataType,              // datatype
-                       firstPixel,                     // writing to the first z-plane
+                       1,                     // writing to the first z-plane
                        numCols*numRows,       // number of elements to write, i.e., the whole image
                        input->data.V[0],      // the data
                        &status);
     } else { // image data may not be contiguous; write one row at a time
+        int firstPixel = 1;
         for (int row = 0; row < numRows; row++) {
             fits_write_img(fits->p_fd,
Index: /trunk/psLib/src/fits/psFits.h
===================================================================
--- /trunk/psLib/src/fits/psFits.h	(revision 2961)
+++ /trunk/psLib/src/fits/psFits.h	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 19:13:53 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -37,5 +37,5 @@
 
 /** FITS file object.
- * 
+ *
  *  This object should be considered opaque to the user; no item in this
  *  struct should be accessed directly.
@@ -51,10 +51,9 @@
 /** Opens a FITS file and allocates the associated psFits object.
  *
- *  @return psFits*    new psFits object for the FITS files specified or 
+ *  @return psFits*    new psFits object for the FITS files specified or
  *                     NULL if the open of the FITS file failed
  */
 psFits* psFitsAlloc(
-    const char* name,                  ///< the FITS file name
-    bool readwrite                     ///< if TRUE, the file is open for read/write.
+    const char* name                   ///< the FITS file name
 );
 
@@ -89,5 +88,5 @@
 /** Get the current extension name.
  *
- *  @return int        Current HDU name of the psFits file or NULL if an 
+ *  @return int        Current HDU name of the psFits file or NULL if an
  *                     error occurred.
  */
@@ -96,7 +95,16 @@
 );
 
+/** Set the current extension's name
+ *
+ *  @return bool       TRUE if the extension was successfully set, otherwise FALSE.
+ */
+bool psFitsSetExtName(
+    psFits* fits,                      ///< the psFits object
+    const char* name                   ///< the extension name
+);
+
 /** Get the total number of HDUs in the FITS file.
  *
- *  @return int        The total number of HDUs in the FITS file or < 0 if an 
+ *  @return int        The total number of HDUs in the FITS file or < 0 if an
  *                     error occurred.
  */
@@ -107,5 +115,5 @@
 /** Get the extension type of the current HDU.
  *
- *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN, 
+ *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN,
  *                     the type could not be determined.
  */
@@ -151,5 +159,5 @@
  *  @return psImage*     the read image or NULL if there was an error.
  */
-psImage* psFitsReadImageSection(
+psImage* psFitsReadImage(
     psImage* out,                      ///< a psImage to recycle.
     psFits* fits,                      ///< the psFits object
@@ -182,5 +190,5 @@
  *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
  *
- *  @return psArray*    Array of data items for the specified column or NULL 
+ *  @return psArray*    Array of data items for the specified column or NULL
  *                      if an error occurred.
  */
@@ -207,5 +215,5 @@
  *  @return psArray*     Array of psMetadata items, which contains the output
  *                       data items of each row.
- *  
+ *
  *  @see psFitsReadTableRow
  */
@@ -218,5 +226,5 @@
  *
  *  @return bool        TRUE if the write was successful, otherwise FALSE
- *  
+ *
  *  @see psFitsReadTableRow
  */
Index: /trunk/psLib/src/image/psImageIO.c
===================================================================
--- /trunk/psLib/src/image/psImageIO.c	(revision 2961)
+++ /trunk/psLib/src/image/psImageIO.c	(revision 2962)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-01-05 21:16:14 $
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -19,4 +19,5 @@
 #include "psError.h"
 #include "psMemory.h"
+#include "psLogMsg.h"
 
 #include "psImageErrors.h"
@@ -46,4 +47,6 @@
     psS32 datatype = 0;
 
+    psLogMsg(__func__,PS_LOG_WARN, "psImageReadSection is deprecated.  Consider using psFitsReadImage instead.");
+
     if (filename == NULL) {
         psError(PS_ERR_BAD_PARAMETER_NULL, true,
@@ -240,4 +243,6 @@
     double bzero = 0.0;
     psBool createNewHDU = false;
+
+    psLogMsg(__func__,PS_LOG_WARN, "psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.");
 
     /* need a valid image to write */
Index: /trunk/psLib/src/pslib.h
===================================================================
--- /trunk/psLib/src/pslib.h	(revision 2961)
+++ /trunk/psLib/src/pslib.h	(revision 2962)
@@ -9,6 +9,6 @@
 *  @author Eric Van Alst, MHPCC
 *
-*  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-11-10 23:39:05 $
+*  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-12 22:17:01 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -172,4 +172,5 @@
 /// @defgroup FileUtils File Utilities
 /// @{
+#include "psFits.h"
 
 /// @defgroup LookupTable Lookup Table
Index: /trunk/psLib/test/dataIO/Makefile
===================================================================
--- /trunk/psLib/test/dataIO/Makefile	(revision 2961)
+++ /trunk/psLib/test/dataIO/Makefile	(revision 2962)
@@ -3,6 +3,6 @@
 ##  Makefile:   test/fileUtils
 ##
-##  $Revision: 1.1 $  $Name: not supported by cvs2svn $
-##  $Date: 2004-11-09 00:49:37 $
+##  $Revision: 1.2 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-12 22:17:02 $
 ##
 ##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -19,5 +19,6 @@
 LDFLAGS := -L../../lib -lpslib -lpstest $(LDFLAGS)
 
-TARGET = tst_psLookupTable_01
+TARGET = tst_psLookupTable_01 \
+	tst_psFits
 
 OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
Index: /trunk/psLib/test/fileUtils/Makefile
===================================================================
--- /trunk/psLib/test/fileUtils/Makefile	(revision 2961)
+++ /trunk/psLib/test/fileUtils/Makefile	(revision 2962)
@@ -3,6 +3,6 @@
 ##  Makefile:   test/fileUtils
 ##
-##  $Revision: 1.1 $  $Name: not supported by cvs2svn $
-##  $Date: 2004-11-09 00:49:37 $
+##  $Revision: 1.2 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-12 22:17:02 $
 ##
 ##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -19,5 +19,6 @@
 LDFLAGS := -L../../lib -lpslib -lpstest $(LDFLAGS)
 
-TARGET = tst_psLookupTable_01
+TARGET = tst_psLookupTable_01 \
+	tst_psFits
 
 OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
