Index: trunk/psLib/src/fits/psFitsTable.c
===================================================================
--- trunk/psLib/src/fits/psFitsTable.c	(revision 7538)
+++ trunk/psLib/src/fits/psFitsTable.c	(revision 7846)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-06-13 22:05:23 $
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-07-08 03:06:40 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -26,141 +26,405 @@
 #include "psFitsTable.h"
 #include "psFitsHeader.h"
+#include "psAbort.h"
+#include "psAssert.h"
 
 #define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
 
-static psElemType convertFitsToPsType(int datatype)
-{
-    switch (datatype) {
-    case TBYTE:
-        return PS_TYPE_U8;
-    case TSBYTE:
-        return PS_TYPE_S8;
-    case TSHORT:
-        return PS_TYPE_S16;
-    case TUSHORT:
-        return PS_TYPE_U16;
-    case TLONG:
-        if (sizeof(long) == 8) {
-            return PS_TYPE_S64;
-        }
-        // no break
-    case TINT:
-        return PS_TYPE_S32;
-    case TULONG:
-        if (sizeof(unsigned long) == 8) {
-            return PS_TYPE_U64;
-        }
-        // no break
-    case TUINT:
-        return PS_TYPE_U32;
-    case TLONGLONG:
-        return PS_TYPE_S64;
-    case TFLOAT:
-        return PS_TYPE_F32;
-    case TDOUBLE:
-        return PS_TYPE_F64;
-    case TCOMPLEX:
-        return PS_TYPE_C32;
-    case TDBLCOMPLEX:
-        return PS_TYPE_C64;
-    case TLOGICAL:
-        return PS_TYPE_BOOL;
+
+psMetadata* psFitsReadTableRow(const psFits* fits,
+                               int row)
+{
+    long numRows;
+    int numCols;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    fits_get_hdu_type(fits->fd,&hdutype, &status);
+    if ( 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 != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    fits_get_num_rows(fits->fd, &numRows, &status);
+    fits_get_num_cols(fits->fd, &numCols, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    psTrace(".psFits.psFitsReadTableRow",5,"Table size is %ix%i\n",numCols, numRows);
+    // the row parameter in the proper range?
+    if (row < 0 || row >= numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psFits_ROW_INVALID,
+                row,numRows);
+        return NULL;
+    }
+
+    psMetadata* data = psMetadataAlloc();
+
+    int typecode;
+    long repeat;
+    long width;
+    char name[60];
+    for (int col = 1; col <= numCols; col++) {
+        // get the column name
+        if (hdutype == BINARY_TBL) {
+            fits_get_bcolparms(fits->fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        } else {
+            fits_get_acolparms(fits->fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        }
+        // get the column type
+        fits_get_coltype(fits->fd, col, &typecode, &repeat, &width, &status);
+
+        if (status == 0) {
+
+            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE, VECTYPE) \
+        case FITSTYPE: { \
+                if (repeat == 1) { \
+                    NATIVETYPE value; \
+                    int anynul = 0; \
+                    fits_read_col(fits->fd, FITSTYPE, col,row+1, \
+                                  1, 1, NULL, &value, &anynul, &status); \
+                    psTrace(".psFits.psFitsReadTableRow",5,"Column #%i, '%s', is type %i, repeat %i, Value = %g\n", \
+                            col, name, typecode, repeat, (double)value); \
+                    psMetadataAdd(data,PS_LIST_TAIL, name, \
+                                  PS_DATA_##TYPE, \
+                                  "", (ps##TYPE)value); \
+                } else { \
+                    NATIVETYPE* value = psAlloc(sizeof(NATIVETYPE)*repeat); \
+                    psVector* vec = psVectorAlloc(repeat,PS_TYPE_##VECTYPE); \
+                    int anynul = 0; \
+                    fits_read_col(fits->fd, FITSTYPE, col,row+1, \
+                                  1, repeat, NULL, value, &anynul, &status); \
+                    for (int lcv = 0; lcv < repeat; lcv++) { \
+                        vec->data.VECTYPE[lcv] = value[lcv]; \
+                    } \
+                    psMetadataAdd(data,PS_LIST_TAIL, name, PS_DATA_VECTOR, "", vec); \
+                    psFree(value); \
+                    psFree(vec); \
+                } \
+                break; \
+            }
+
+            switch (typecode) {
+            case TBYTE:
+            case TSHORT:
+            case TLONGLONG:
+                READ_TABLE_ROW_CASE(TLONG, long, S32,S32)
+                READ_TABLE_ROW_CASE(TFLOAT, float, F32,F32)
+                READ_TABLE_ROW_CASE(TDOUBLE, double, F64,F64)
+                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL,S8);
+            case TSTRING: {
+                    char* value = psAlloc(repeat+1);
+                    int anynul = 0;
+                    fits_read_col(fits->fd, TSTRING, col,row+1,
+                                  1, 1, NULL, &value, &anynul, &status);
+                    psTrace(".psFits.psFitsReadTableRow",5,"Column #%i, '%s', is type %i, repeat %i, value = %s\n",
+                            col, name, typecode, repeat, value);
+                    if (anynul == 0) {
+                        psMetadataAdd(data,PS_LIST_TAIL, name,
+                                      PS_DATA_STRING,
+                                      "", value);
+                    }
+                    psFree(value);
+                    break;
+                }
+            default:
+                psWarning("Data type (%d) not supportted for column %d",
+                          typecode, col);
+
+                psTrace("psFits.psFitsReadTableRow", 2,
+                        "Column %d or row %d was of a non primitive type, %d",
+                        col, row, typecode);
+            }
+        }
+
+        if ( status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            (void)fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
+                    col,row,fitsErr);
+            psFree(data);
+            return NULL;
+        }
+
+    }
+
+    return data;
+}
+
+psArray* psFitsReadTableColumn(const psFits* fits,
+                               const char* colname)
+{
+    int colnum = 0;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->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 != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->fd, &numRows, &status);
+
+    // get the column length.
+    int width;
+    if ( fits_get_col_display_width(fits->fd, colnum, &width, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_COLTYPE,
+                fitsErr);
+        return NULL;
+    }
+
+    // allocate the buffers
+    psArray* result = psArrayAlloc(numRows);
+    for (int row = 0; row < numRows; row++) {
+        result->data[row] = psAlloc((width+1)*sizeof(char));
+    }
+    result->n = numRows;
+
+    fits_read_col_str(fits->fd,
+                      colnum,
+                      1, // firstrow
+                      1, // firestelem
+                      numRows,
+                      "", // nulstr
+                      (char**)result->data,
+                      NULL,
+                      &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+psVector* psFitsReadTableColumnNum(const psFits* fits,
+                                   const char* colname)
+{
+    int status = 0;
+    int colnum = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->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 != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->fd,
+                      &numRows,
+                      &status);
+
+    // get the column datatype.
+    int typecode;
+    long repeat;
+    long width;
+    if ( fits_get_eqcoltype(fits->fd, colnum, &typecode, &repeat, &width, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_COLTYPE,
+                fitsErr);
+        return NULL;
+    }
+
+    psVector* result = psVectorAlloc(numRows, p_psFitsTypeFromCfitsio(typecode));
+    result->n = numRows;
+
+    fits_read_col(fits->fd,
+                  typecode,
+                  colnum,
+                  1 /* firstrow */,
+                  1 /* firstelem */,
+                  numRows,
+                  NULL,
+                  (psPtr)(result->data.U8),
+                  NULL,
+                  &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+
+psArray* psFitsReadTable(const psFits* fits)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->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 != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    long numRows = 0;
+    fits_get_num_rows(fits->fd, &numRows, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+
+    psArray* table = psArrayAlloc(numRows);
+
+    for (int row = 0; row < numRows; row++) {
+        psTrace(".psFits.psFitsReadTable",5,"Reading row %i of %i\n",row, numRows);
+        table->data[row] = psFitsReadTableRow(fits,row);
+        table->n++;
+    }
+
+    return table;
+}
+
+bool psFitsWriteTable(psFits* fits,
+                      const psMetadata* header,
+                      const psArray* table,
+                      const char *extname)
+{
+    psFitsMoveLast(fits);
+    return psFitsInsertTable(fits, header, table, extname, true);
+}
+
+
+// Return the size of the column
+static inline size_t columnSize(const psMetadataItem *item // Item for which to get the size
+                               )
+{
+    if (PS_DATA_IS_PRIMITIVE(item->type)) {
+        return 1;
+    }
+    switch (item->type) {
+    case PS_DATA_STRING:
+        return strlen(item->data.V);
+    case PS_DATA_VECTOR: {
+            psVector *vector = item->data.V;
+            return vector->n;
+        }
     default:
-        psError(PS_ERR_IO, true,
-                "Unknown FITS datatype, %d.",
-                datatype);
-        return 0;
-    }
-}
-
-static bool convertPsTypeToFits(int type, int* bitPix, double* bZero, int* dataType)
-{
-
-    int bitpix;
-    int datatype;
-    double bzero = 0.0;
-
-    switch (type) {
-
-    case PS_TYPE_U8:
-        bitpix = BYTE_IMG;
-        datatype = TBYTE;
-        break;
-
-    case PS_TYPE_S8:
-        bitpix = BYTE_IMG;
-        bzero = INT8_MIN;
-        datatype = TSBYTE;
-        break;
-
-    case PS_TYPE_U16:
-        bitpix = SHORT_IMG;
-        bzero = -1.0 * INT16_MIN;
-        datatype = TUSHORT;
-        break;
-
-    case PS_TYPE_S16:
-        bitpix = SHORT_IMG;
-        datatype = TSHORT;
-        break;
-
-    case PS_TYPE_U32:
-        bitpix = LONG_IMG;
-        bzero = -1.0 * INT32_MIN;
-        datatype = TUINT;
-        break;
-
-    case PS_TYPE_S32:
-        bitpix = LONG_IMG;
-        datatype = TINT;
-        break;
-
-    case PS_TYPE_F32:
-        bitpix = FLOAT_IMG;
-        datatype = TFLOAT;
-        break;
-
-    case PS_TYPE_F64:
-        bitpix = DOUBLE_IMG;
-        datatype = TDOUBLE;
-        break;
-
-    case PS_DATA_STRING:
-        bitpix = BYTE_IMG;
-        datatype = TSTRING;
-        break;
-
-    case PS_DATA_BOOL:
-        bitpix = BYTE_IMG;
-        datatype = TLOGICAL;
-        break;
-
-    default: {
-            char* typeStr;
-            PS_TYPE_NAME(typeStr,type);
-            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                    PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED,
-                    typeStr);
-            return false;
-        }
-    }
-
-    // pass the requested parameters  (NULL parameters are not set, of course).
-    if (bitPix != NULL) {
-        *bitPix = bitpix;
-    }
-
-    if (dataType != NULL) {
-        *dataType = datatype;
-    }
-
-    if (bZero != NULL) {
-        *bZero = bzero;
-    }
-
-    return true;
-}
-
-static char getTForm(int type)
+        psAbort(__func__, "Shouldn't ever get here.");
+    }
+    return 0;
+}
+
+// Get the TFORM character, given a PS type
+static inline const char getTForm(psDataType type)
 {
     switch (type) {
@@ -196,420 +460,15 @@
 }
 
-static bool getMetadataTForm(psMetadataItem* item, char** fitsType, int repeat)
-{
-    if (item == NULL) {
-        return false;
-    }
-
-    *fitsType = NULL;
-    char tform = getTForm(item->type);
-
-    switch (item->type) {
-    case PS_TYPE_U8:
-    case PS_TYPE_S8:
-    case PS_TYPE_S16:
-    case PS_TYPE_S32:
-    case PS_TYPE_U64:
-    case PS_TYPE_S64:
-    case PS_TYPE_U16:
-    case PS_TYPE_U32:
-    case PS_TYPE_F32:
-    case PS_TYPE_F64:
-    case PS_TYPE_C32:
-    case PS_TYPE_C64:
-    case PS_TYPE_BOOL:
-        psStringAppend(fitsType, "%d%c",repeat,tform);
-        break;
-
-    case PS_DATA_STRING:
-        psStringAppend(fitsType,"%dA",
-                       strlen(item->data.V)*repeat);
-        break;
-
-    case PS_DATA_VECTOR: {
-            psVector* vec = item->data.V;
-            tform = getTForm(vec->type.type);
-            psStringAppend(fitsType,"%d%c",repeat*vec->n,tform);
-        }
-        break;
-
-    default:
-        return false;
-    }
-
-    return true;
-}
-
-psMetadata* psFitsReadTableRow(const psFits* fits,
-                               int row)
-{
-    long numRows;
-    int numCols;
-    int status = 0;
-
-    if (fits == NULL) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psFits_NULL);
-        return NULL;
-    }
-
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    fits_get_hdu_type(fits->fd,&hdutype, &status);
-    if ( 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 != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
-        return NULL;
-    }
-
-    // get the size of the FITS table
-    fits_get_num_rows(fits->fd, &numRows, &status);
-    fits_get_num_cols(fits->fd, &numCols, &status);
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
-                fitsErr);
-        return NULL;
-    }
-
-    psTrace(".psFits.psFitsReadTableRow",5,"Table size is %ix%i\n",numCols, numRows);
-    // the row parameter in the proper range?
-    if (row < 0 || row >= numRows) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                PS_ERRORTEXT_psFits_ROW_INVALID,
-                row,numRows);
-        return NULL;
-    }
-
-    psMetadata* data = psMetadataAlloc();
-
-    int typecode;
-    long repeat;
-    long width;
-    char name[60];
-    for (int col = 1; col <= numCols; col++) {
-        // get the column name
-        if (hdutype == BINARY_TBL) {
-            fits_get_bcolparms(fits->fd, col, name,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
-        } else {
-            fits_get_acolparms(fits->fd, col, name,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
-        }
-        // get the column type
-        fits_get_coltype(fits->fd, col, &typecode, &repeat, &width, &status);
-
-        if (status == 0) {
-
-            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE, VECTYPE) \
-        case FITSTYPE: { \
-                if (repeat == 1) { \
-                    NATIVETYPE value; \
-                    int anynul = 0; \
-                    fits_read_col(fits->fd, FITSTYPE, col,row+1, \
-                                  1, 1, NULL, &value, &anynul, &status); \
-                    psTrace(".psFits.psFitsReadTableRow",5,"Column #%i, '%s', is type %i, repeat %i, Value = %g\n", \
-                            col, name, typecode, repeat, (double)value); \
-                    psMetadataAdd(data,PS_LIST_TAIL, name, \
-                                  PS_DATA_##TYPE, \
-                                  "", (ps##TYPE)value); \
-                } else { \
-                    NATIVETYPE* value = psAlloc(sizeof(NATIVETYPE)*repeat); \
-                    psVector* vec = psVectorAlloc(repeat,PS_TYPE_##VECTYPE); \
-                    int anynul = 0; \
-                    fits_read_col(fits->fd, FITSTYPE, col,row+1, \
-                                  1, repeat, NULL, value, &anynul, &status); \
-                    for (int lcv = 0; lcv < repeat; lcv++) { \
-                        vec->data.VECTYPE[lcv] = value[lcv]; \
-                    } \
-                    psMetadataAdd(data,PS_LIST_TAIL, name, PS_DATA_VECTOR, "", vec); \
-                    psFree(value); \
-                    psFree(vec); \
-                } \
-                break; \
-            }
-
-            switch (typecode) {
-            case TBYTE:
-            case TSHORT:
-            case TLONGLONG:
-                READ_TABLE_ROW_CASE(TLONG, long, S32,S32)
-                READ_TABLE_ROW_CASE(TFLOAT, float, F32,F32)
-                READ_TABLE_ROW_CASE(TDOUBLE, double, F64,F64)
-                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL,S8);
-            case TSTRING: {
-                    char* value = psAlloc(repeat+1);
-                    int anynul = 0;
-                    fits_read_col(fits->fd, TSTRING, col,row+1,
-                                  1, 1, NULL, &value, &anynul, &status);
-                    psTrace(".psFits.psFitsReadTableRow",5,"Column #%i, '%s', is type %i, repeat %i, value = %s\n",
-                            col, name, typecode, repeat, value);
-                    if (anynul == 0) {
-                        psMetadataAdd(data,PS_LIST_TAIL, name,
-                                      PS_DATA_STRING,
-                                      "", value);
-                    }
-                    psFree(value);
-                    break;
-                }
-            default:
-                psWarning("Data type (%d) not supportted for column %d",
-                          typecode, col);
-
-                psTrace("psFits.psFitsReadTableRow", 2,
-                        "Column %d or row %d was of a non primitive type, %d",
-                        col, row, typecode);
-            }
-        }
-
-        if ( status != 0) {
-            char fitsErr[MAX_STRING_LENGTH];
-            (void)fits_get_errstatus(status, fitsErr);
-            psError(PS_ERR_IO, true,
-                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
-                    col,row,fitsErr);
-            psFree(data);
-            return NULL;
-        }
-
-    }
-
-    return data;
-}
-
-psArray* psFitsReadTableColumn(const psFits* fits,
-                               const char* colname)
-{
-    int colnum = 0;
-    int status = 0;
-
-    if (fits == NULL) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psFits_NULL);
-        return NULL;
-    }
-
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    if ( fits_get_hdu_type(fits->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 != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
-        return NULL;
-    }
-
-    // find the column by name
-    if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_FIND_COLUMN,
-                colname, fitsErr);
-        return NULL;
-    }
-
-    // get the number of rows
-    long numRows = 0;
-    fits_get_num_rows(fits->fd, &numRows, &status);
-
-    // get the column length.
-    int width;
-    if ( fits_get_col_display_width(fits->fd, colnum, &width, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_GET_COLTYPE,
-                fitsErr);
-        return NULL;
-    }
-
-    // allocate the buffers
-    psArray* result = psArrayAlloc(numRows);
-    for (int row = 0; row < numRows; row++) {
-        result->data[row] = psAlloc((width+1)*sizeof(char));
-    }
-    result->n = numRows;
-
-    fits_read_col_str(fits->fd,
-                      colnum,
-                      1, // firstrow
-                      1, // firestelem
-                      numRows,
-                      "", // nulstr
-                      (char**)result->data,
-                      NULL,
-                      &status);
-
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_TABLE_READ_COL,
-                fitsErr);
-        return NULL;
-    }
-
-    return result;
-}
-
-psVector* psFitsReadTableColumnNum(const psFits* fits,
-                                   const char* colname)
-{
-    int status = 0;
-    int colnum = 0;
-
-    if (fits == NULL) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psFits_NULL);
-        return NULL;
-    }
-
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    if ( fits_get_hdu_type(fits->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 != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
-        return NULL;
-    }
-
-    // find the column by name
-    if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_FIND_COLUMN,
-                colname, fitsErr);
-        return NULL;
-    }
-
-    // get the number of rows
-    long numRows = 0;
-    fits_get_num_rows(fits->fd,
-                      &numRows,
-                      &status);
-
-    // get the column datatype.
-    int typecode;
-    long repeat;
-    long width;
-    if ( fits_get_eqcoltype(fits->fd, colnum, &typecode, &repeat, &width, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_GET_COLTYPE,
-                fitsErr);
-        return NULL;
-    }
-
-    psVector* result = psVectorAlloc(numRows, convertFitsToPsType(typecode));
-    result->n = numRows;
-
-    fits_read_col(fits->fd,
-                  typecode,
-                  colnum,
-                  1 /* firstrow */,
-                  1 /* firstelem */,
-                  numRows,
-                  NULL,
-                  (psPtr)(result->data.U8),
-                  NULL,
-                  &status);
-
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_TABLE_READ_COL,
-                fitsErr);
-        return NULL;
-    }
-
-    return result;
-}
-
-
-psArray* psFitsReadTable(const psFits* fits)
-{
-    int status = 0;
-
-    if (fits == NULL) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psFits_NULL);
-        return NULL;
-    }
-
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    if ( fits_get_hdu_type(fits->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 != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
-        return NULL;
-    }
-
-    // get the size of the FITS table
-    long numRows = 0;
-    fits_get_num_rows(fits->fd, &numRows, &status);
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
-                fitsErr);
-        return NULL;
-    }
-
-
-    psArray* table = psArrayAlloc(numRows);
-
-    for (int row = 0; row < numRows; row++) {
-        psTrace(".psFits.psFitsReadTable",5,"Reading row %i of %i\n",row, numRows);
-        table->data[row] = psFitsReadTableRow(fits,row);
-        table->n++;
-    }
-
-    return table;
-}
-
-bool psFitsWriteTable(psFits* fits,
-                      const psMetadata* header,
-                      const psArray* table,
-                      const char *extname)
-{
-    psFitsMoveLast(fits);
-    return psFitsInsertTable(fits, header, table, extname, true);
-}
+
+// Column specification
+// Included here, because there's no need for the user to have access to it
+typedef struct
+{
+    psDataType type;                    // psLib type (e.g., PS_DATA_STRING or PS_TYPE_F32)
+    size_t size;                        // Size (number of repeats)
+    psElemType vectorType;              // psLib type of vectors
+}
+colSpec;
+
 
 bool psFitsInsertTable(psFits* fits,
@@ -621,18 +480,9 @@
     int status = 0;
 
-    if (fits == NULL) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psFits_NULL);
-        return false;
-    }
-
-    if (table == NULL) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psFits_IMAGE_NULL);
-        return false;
-    }
-
-    int rows = table->n;
-    if (rows < 1) {
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+    PS_ASSERT_ARRAY_NON_NULL(table, false);
+
+    long numRows = table->n;
+    if (numRows < 1) {
         // no table data, what can I do?
         psError(PS_ERR_BAD_PARAMETER_SIZE, true,
@@ -641,97 +491,96 @@
     }
 
-    // find all the columns needed
-    psArray* columns = psArrayAlloc(((psMetadata*)table->data[0])->list->n);
-    columns->n=0;
-
-    // find the unique items in the array of metadata 'rows'
-    psMetadataItem* item;
-    for (int row=0; row < rows; row++) {
-        psMetadata* rowMeta = table->data[row];
-        if (rowMeta != NULL) {
-            psListIterator* iter = psListIteratorAlloc(rowMeta->list,
-                                   PS_LIST_HEAD,true);
-            while ( (item=psListGetAndIncrement(iter)) != NULL) {
-                if (PS_DATA_IS_PRIMITIVE(item->type) ||
-                        item->type == PS_DATA_STRING ||
-                        item->type == PS_DATA_VECTOR) {
-                    bool found = false;
-                    psMetadataItem* fItem = NULL;
-                    int n;
-                    for (n=0; n < columns->n && ! found; n++) {
-                        fItem = (psMetadataItem*)(columns->data[n]);
-                        if (strcmp(item->name, fItem->name) == 0) {
-                            found = true;
-                            break;
-                        }
+    // Find the unique items in the array of metadata 'rows', and their sizes
+    psMetadata *colSpecs = psMetadataAlloc(); // Column specifications
+    size_t rowSize = 0;                 // Size (in bytes) of each row
+    for (long i = 0; i < numRows; i++) {
+        psMetadata* row = table->data[i];
+        if (!row) {
+            continue;
+        }
+        psMetadataIterator *rowIter = psMetadataIteratorAlloc(row, PS_LIST_HEAD, NULL); // Iterator
+        psMetadataItem *colItem;        // Column item, from iteration
+        while ((colItem = psMetadataGetAndIncrement(rowIter))) {
+            if (!(PS_DATA_IS_PRIMITIVE(colItem->type) || colItem->type == PS_DATA_STRING ||
+                    colItem->type == PS_DATA_VECTOR)) {
+                // unsupported type -- treating as an error
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        "Unsupported data type (%d) for Metadata Item '%s' in row %d.",
+                        colItem->type, colItem->name, row);
+                psFree(rowIter);
+                psFree(colSpecs);
+                return false;
+            }
+
+            size_t size = columnSize(colItem); // Size for this column
+
+            // Check to see if we know about this one; or update the size if required
+            psMetadataItem *colSpecItem = psMetadataLookup(colSpecs, colItem->name);
+            if (!colSpecItem) {
+                // A new one!
+                colSpec *spec = psAlloc(sizeof(colSpec)); // Specification for this column
+                spec->type = colItem->type;
+                spec->size = size;
+                if (colItem->type == PS_DATA_VECTOR) {
+                    psVector *vector = colItem->data.V; // The vector
+                    spec->vectorType = vector->type.type;
+                }
+                psMetadataAddPtr(colSpecs, PS_LIST_TAIL, colItem->name, PS_DATA_UNKNOWN, "", spec);
+                psFree(spec);           // Drop reference
+                rowSize += PSELEMTYPE_SIZEOF(spec->type);
+            } else {
+                colSpec *spec = colSpecItem->data.V; // The specification
+                if (size > spec->size) {
+                    spec->size = size;
+                }
+                if (colItem->type != spec->type) {
+                    psLogMsg(__func__, PS_LOG_WARN, "Differing type found for column %s: %x vs %x --- "
+                             "using the first found.\n", colSpecItem->name, colItem->type, spec->type);
+                }
+                if (colItem->type == PS_DATA_VECTOR) {
+                    psVector *vector = colItem->data.V; // The vector
+                    if (vector->type.type != spec->vectorType) {
+                        psLogMsg(__func__, PS_LOG_WARN, "Differing vector type found for column %s: %x vs %x"
+                                 "--- using the first found.\n", colSpecItem->name, vector->type.type,
+                                 spec->vectorType);
                     }
-                    if (! found) {
-                        psArrayAdd(columns, columns->nalloc, item);
-                    } else if (item->type == PS_DATA_STRING &&
-                               strlen(fItem->data.V) < strlen(item->data.V)) {
-                        // got to keep the longest string value as to know what size to create the table column
-                        psMemDecrRefCounter(fItem);
-                        columns->data[n] = psMemIncrRefCounter(item);
-                        columns->n++;
-
-                    } else if (item->type == PS_DATA_VECTOR &&
-                               ((psVector*)(fItem->data.V))->n < ((psVector*)(item->data.V))->n) {
-                        psMemDecrRefCounter(fItem);
-                        columns->data[n] = psMemIncrRefCounter(item);
-                        columns->n++;
-                    }
-                } else {
-                    // unsupported type -- treating as an error
-                    psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                            "Unsupported data type (%d) for Metadata Item '%s' in row %d.",
-                            item->type, item->name, row);
-                    psFree(iter);
-                    psFree(columns);
-                    return false;
                 }
             }
-            psFree(iter);
-        }
-    }
-
-    if (columns->n == 0) { // no table columns found
+        }
+        psFree(rowIter);
+    }
+
+    long numColumns = colSpecs->list->n;// Number of columns
+    if (numColumns == 0) {
+        // No table columns found
         psError(PS_ERR_BAD_PARAMETER_SIZE, true,
                 "Did not find any column data to write to a table.");
-        psFree(columns);
+        psFree(colSpecs);
         return false;
     }
 
-    //create list of column names and types.
-    if (columns->n > 0) {  // If we're going decrement columns->n (why?), at least free the memory
-        psFree(columns->data[columns->n - 1]);
-    }
-    columns->n--;
-    psArray* columnNames = psArrayAlloc(columns->n);
-    psArray* columnTypes = psArrayAlloc(columns->n);
-    for (int n=0; n < columns->n; n++) {
-        columnNames->data[n] = psMemIncrRefCounter(((psMetadataItem*)columns->data[n])->name);
-        columnNames->n++;
-        columnTypes->n++;
-        if ( ! getMetadataTForm((psMetadataItem*)columns->data[n],
-                                (char**)&(columnTypes->data[n]),1) ) {
-            psError(PS_ERR_UNKNOWN, true,
-                    "Failed to determine the FITS data type of '%s' (type=%d).",
-                    columnNames->data[n],
-                    ((psMetadataItem*)columns->data[n])->type);
-            psFree(columns);
-            psFree(columnNames);
-            psFree(columnTypes);
-            return false;
-        }
+    // Create array of column names and types.
+    psArray *columnNames = psArrayAlloc(numColumns); // Array of column names, for cfitsio
+    psArray *columnTypes = psArrayAlloc(numColumns); // Array of column types, for cfitsio
+    columnNames->n = numColumns;
+    columnTypes->n = numColumns;
+    psMetadataIterator *colSpecsIter = psMetadataIteratorAlloc(colSpecs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *colSpecItem;        // Column specification item, from iteration
+    for (long i = 0; (colSpecItem = psMetadataGetAndIncrement(colSpecsIter)); i++) {
+        colSpec *spec = colSpecItem->data.V; // The specification
+        columnNames->data[i] = psMemIncrRefCounter(colSpecItem->name);
+        psString colType = NULL;        // The column type
+        psStringAppend(&colType, "%d%c", spec->size, getTForm(spec->type));
+        columnTypes->data[i] = colType;
     }
 
     // Create the table HDU
-    int hdus = psFitsGetSize(fits);     // Number of HDUs in file
-    if (hdus == 0) {
+    int numHDUs = psFitsGetSize(fits);  // Number of HDUs in file
+    if (numHDUs == 0) {
         // We're creating the first extension
         fits_create_tbl(fits->fd,
                         BINARY_TBL,
                         table->n, // number of rows in table
-                        columns->n, // number of columns in table
+                        numColumns, // number of columns in table
                         (char**)columnNames->data, // names of the columns
                         (char**)columnTypes->data, // format of the columns
@@ -753,11 +602,10 @@
         fits_insert_btbl(fits->fd,
                          table->n, // number of rows in table
-                         columns->n, // number of columns in table
+                         numColumns, // number of columns in table
                          (char**)columnNames->data, // names of the columns
                          (char**)columnTypes->data, // format of the columns
                          NULL, // physical unit of columns
                          (char*)extname, // extension name; casting away const because cfitsio is horrible
-                         0,
-                         &status);
+                         0, &status);
     }
     psFree(columnNames);
@@ -770,81 +618,75 @@
     }
 
-    // fill in the table elements with data
-    for (int n = 0; n < columns->n; n++) {
-        int row;
-        item = columns->data[n];
-        if (PS_DATA_IS_PRIMITIVE(item->type) ) {
-            psVector* col = psVectorAlloc(table->n, item->type);
-            int dataSize = PSELEMTYPE_SIZEOF(item->type);
-            int dataType;
-            convertPsTypeToFits(item->type, NULL,NULL,&dataType);
-            for (row = 0; row < table->n; row++) {
-                psMetadataItem* dataItem = psMetadataLookup(
-                                               table->data[row],
-                                               item->name);
-                memcpy(&col->data.U8[row*dataSize],&dataItem->data,dataSize);
-            }
+
+    // cfitsio requires that we write the data by columns --- urgh!
+    psMetadataIteratorSet(colSpecsIter, PS_LIST_HEAD);
+    for (long colNum = 1; (colSpecItem = psMetadataGetAndIncrement(colSpecsIter)); colNum++) {
+        // Note: colNum is unit-indexed, because it's for cfitsio
+        colSpec *spec = colSpecItem->data.V; // The specification
+        if (PS_DATA_IS_PRIMITIVE(spec->type)) {
+            size_t dataSize = PSELEMTYPE_SIZEOF(spec->type); // Size (in bytes) of this type
+            psVector *columnData = psVectorAlloc(table->n, spec->type); // The raw row data, to be written
+            psVectorInit(columnData, 0);
+            for (long i = 0; i < table->n; i++) {
+                psMetadata *row = table->data[i]; // The row of interest
+                psMetadataItem *dataItem = psMetadataLookup(row, colSpecItem->name); // The value of interest
+                memcpy(&columnData->data.U8[i * dataSize], &dataItem->data, dataSize);
+            }
+
+            int fitsDataType;           // Data type for cfitsio
+            p_psFitsTypeToCfitsio(spec->type, NULL, NULL, &fitsDataType);
             fits_write_col(fits->fd,
-                           dataType,
-                           n+1, // column number
-                           1, // firstrow
-                           1, // firstelem
-                           table->n, // nelements
-                           col->data.U8,
+                           fitsDataType,
+                           colNum, // column number
+                           1, // first row
+                           1, // first element
+                           table->n, // number of rows
+                           columnData->data.U8, // the data
                            &status);
-            psFree(col);
-        } else if (item->type == PS_DATA_STRING) {
-            psArray* colArray = psArrayAlloc(table->n);
-            for (row = 0; row < table->n; row++) {
-                colArray->data[row] = psStringCopy(psMetadataLookupStr(NULL,
-                                                   table->data[row],
-                                                   item->name));
-                colArray->n++;
-            }
-            fits_write_col_str(fits->fd,
-                               n+1,
-                               1,
-                               1,
-                               table->n,
-                               (char**)colArray->data,
+            psFree(columnData);
+            continue;
+        }
+
+        switch (spec->type) {
+        case PS_DATA_STRING: {
+                psArray *strings = psArrayAlloc(table->n); // Array of strings
+                strings->n = table->n;
+                for (long i = 0; i < table->n; i++) {
+                    psMetadata *row = table->data[i]; // The row of interest
+                    strings->data[i] = psMemIncrRefCounter(psMetadataLookupStr(NULL, row, colSpecItem->name));
+                }
+                fits_write_col_str(fits->fd, colNum, 1, 1, table->n, (char**)strings->data, &status);
+                psFree(strings);
+                break;
+            }
+        case PS_DATA_VECTOR: {
+                psVector *columnData = psVectorAlloc(spec->size * table->n, spec->vectorType);
+                psVectorInit(columnData, 0);
+                size_t dataSize = PSELEMTYPE_SIZEOF(spec->vectorType); // Size of data, in bytes
+                for (long i = 0; i < table->n; i++) {
+                    psMetadata *row = table->data[i]; // The row of interest
+                    psMetadataItem* dataItem = psMetadataLookup(row, colSpecItem->name);
+                    if (dataItem->type != PS_DATA_VECTOR) {
+                        // Just in case --- get a zero instead of some weird result
+                        continue;
+                    }
+                    psVector *vector = dataItem->data.V;
+                    memcpy(&columnData->data.U8[i * dataSize], vector->data.U8, dataSize);
+                }
+
+                int fitsDataType;           // Data type for cfitsio
+                p_psFitsTypeToCfitsio(spec->vectorType, NULL, NULL, &fitsDataType);
+                fits_write_col(fits->fd, fitsDataType, colNum, 1, 1, table->n * spec->size, columnData->data.U8,
                                &status);
-            psFree(colArray);
-        } else if (item->type == PS_DATA_VECTOR) {
-            psVector* vec = (psVector*)(item->data.V);
-            psVector* col = psVectorAlloc(table->n*vec->n, vec->type.type);
-            int dataSize = PSELEMTYPE_SIZEOF(vec->type.type)*vec->n;
-            int dataType;
-            convertPsTypeToFits(vec->type.type, NULL,NULL,&dataType);
-            for (row = 0; row < table->n; row++) {
-                psMetadataItem* dataItem = psMetadataLookup(
-                                               table->data[row],
-                                               item->name);
-                memcpy(&col->data.U8[row*dataSize],
-                       ((psVector*)(dataItem->data.V))->data.U8,
-                       dataSize);
-            }
-            fits_write_col(fits->fd,
-                           dataType,
-                           n+1, // column number
-                           1, // firstrow
-                           1, // firstelem
-                           table->n*vec->n, // nelements
-                           col->data.U8,
-                           &status);
-            psFree(col);
-        }
-        if (status != 0) {
-            char fitsErr[MAX_STRING_LENGTH];
-            (void)fits_get_errstatus(status, fitsErr);
-            psError(PS_ERR_IO, true,
-                    PS_ERRORTEXT_psFits_WRITE_FAILED,
-                    fitsErr);
-            psFree(columns);
-            return false;
-        }
-
-    }
-
-    psFree(columns);
+                psFree(columnData);
+                break;
+            }
+        default:
+            psAbort(__func__, "Should never get here.\n");
+        }
+    }
+
+    psFree(colSpecsIter);
+    psFree(colSpecs);
 
     return true;
@@ -899,5 +741,5 @@
                 // cooresponding column found in table
                 int dataType;
-                convertPsTypeToFits(item->type, NULL, NULL, &dataType);
+                p_psFitsTypeToCfitsio(item->type, NULL, NULL, &dataType);
 
                 if (fits_write_col(fits->fd, dataType, colnum, row+1, 1, 1, &item->data,&status) != 0) {
