IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 2806


Ignore:
Timestamp:
Dec 23, 2004, 9:13:53 AM (22 years ago)
Author:
desonia
Message:

added functions to psFits

Location:
trunk/psLib/src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/dataIO/psFileUtilsErrors.dat

    r2681 r2806  
    2525psFits_GETHDUTYPE_FAILED               Failed to determine an HDU type in file %s.\nCFITSIO Error: %s
    2626psFits_GETNUMKEYS_FAILED               Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s
     27psFits_GET_TABLE_SIZE_FAILED           Failed to determine the size of the current HDU table.\nCFITSIO Error: %s
    2728psFits_FILENAME_CREATE_FAILED          Could not create file,'%s'.\nCFITSIO Error: %s
    2829psFits_TYPE_UNSUPPORTED                Specified type, %s, is not supported.
    2930psFits_CREATE_HDU_FAILED               Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s
    30 psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an IMAGE.
     31psFits_GET_HDU_TYPE_FAILED             Could not determine the HDU type.\nCFITSIO Error: %s
     32psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an image.
     33psFits_NOT_TABLE_TYPE                  Current FITS HDU type must be a table.
    3134psFits_TABLE_FIRSTROW_NULL             Can't create a table without the first row, where table column information is derived.
    3235psFits_CFITSIO_ERROR                   CFITSIO error: %s
    3336psFits_METATYPE_INVALID                Specified FITS metadata type, %c, is not supported.
    3437psFits_METADATA_ADD_FAILED             Failed to add metadata item, %s.
    35 psFits_WRITE_FAILED                    Could not write psImage data to file,'%s'.\nCFITSIO Error: %s
     38psFits_WRITE_FAILED                    Could not write data to file,'%s'.\nCFITSIO Error: %s
    3639psFits_IMAGE_NULL                      The input psImage was NULL.  Need a non-NULL psImage for operation to be performed.
    3740psFits_METADATA_NULL                   The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed.
     41psFits_METADATA_PTYPE_UNSUPPORTED      A metadata item's primative type, %d, is not supported.
     42psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows. 
     43psFits_GET_TABLE_ELEMENT               Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s
     44psFits_FIND_COLUMN                     Specified column, %s, was not found.\nCFITSIO Error: %s
     45psFits_GET_COLTYPE                     Could not determine the datatype of the table column.\nCFITSIO Error: %s
     46psFits_TABLE_READ_COL                  Failed to read table column.\nCFITSIO Error: %s
    3847#
  • trunk/psLib/src/dataIO/psFileUtilsErrors.h

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    4747#define PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED "Failed to determine an HDU type in file %s.\nCFITSIO Error: %s"
    4848#define PS_ERRORTEXT_psFits_GETNUMKEYS_FAILED "Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s"
     49#define PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED "Failed to determine the size of the current HDU table.\nCFITSIO Error: %s"
    4950#define PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED "Could not create file,'%s'.\nCFITSIO Error: %s"
    5051#define PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED "Specified type, %s, is not supported."
    5152#define PS_ERRORTEXT_psFits_CREATE_HDU_FAILED "Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s"
    52 #define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an IMAGE."
     53#define PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED "Could not determine the HDU type.\nCFITSIO Error: %s"
     54#define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an image."
     55#define PS_ERRORTEXT_psFits_NOT_TABLE_TYPE "Current FITS HDU type must be a table."
    5356#define PS_ERRORTEXT_psFits_TABLE_FIRSTROW_NULL "Can't create a table without the first row, where table column information is derived."
    5457#define PS_ERRORTEXT_psFits_CFITSIO_ERROR "CFITSIO error: %s"
    5558#define PS_ERRORTEXT_psFits_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."
    5659#define PS_ERRORTEXT_psFits_METADATA_ADD_FAILED "Failed to add metadata item, %s."
    57 #define PS_ERRORTEXT_psFits_WRITE_FAILED "Could not write psImage data to file,'%s'.\nCFITSIO Error: %s"
     60#define PS_ERRORTEXT_psFits_WRITE_FAILED "Could not write data to file,'%s'.\nCFITSIO Error: %s"
    5861#define PS_ERRORTEXT_psFits_IMAGE_NULL "The input psImage was NULL.  Need a non-NULL psImage for operation to be performed."
    5962#define PS_ERRORTEXT_psFits_METADATA_NULL "The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed."
     63#define PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED "A metadata item's primative type, %d, is not supported."
     64#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows.  "
     65#define PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT "Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s"
     66#define PS_ERRORTEXT_psFits_FIND_COLUMN "Specified column, %s, was not found.\nCFITSIO Error: %s"
     67#define PS_ERRORTEXT_psFits_GET_COLTYPE "Could not determine the datatype of the table column.\nCFITSIO Error: %s"
     68#define PS_ERRORTEXT_psFits_TABLE_READ_COL "Failed to read table column.\nCFITSIO Error: %s"
    6069//~End
    6170
  • trunk/psLib/src/dataIO/psFits.c

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2222#include "psString.h"
    2323#include "psLogMsg.h"
     24#include "psTrace.h"
    2425
    2526#define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
     27
     28static psElemType convertFitsToPsType(int datatype)
     29{
     30    switch (datatype) {
     31    case TBYTE:
     32        return PS_TYPE_U8;
     33    case TSBYTE:
     34        return PS_TYPE_S8;
     35    case TSHORT:
     36        return PS_TYPE_S16;
     37    case TUSHORT:
     38        return PS_TYPE_U16;
     39    case TLONG:
     40        if (sizeof(long) == 8) {
     41            return PS_TYPE_S64;
     42        }
     43        // no break
     44    case TINT:
     45        return PS_TYPE_S32;
     46    case TULONG:
     47        if (sizeof(unsigned long) == 8) {
     48            return PS_TYPE_U64;
     49        }
     50        // no break
     51    case TUINT:
     52        return PS_TYPE_U32;
     53    case TLONGLONG:
     54        return PS_TYPE_S64;
     55    case TFLOAT:
     56        return PS_TYPE_F32;
     57    case TDOUBLE:
     58        return PS_TYPE_F64;
     59    case TCOMPLEX:
     60        return PS_TYPE_C32;
     61    case TDBLCOMPLEX:
     62        return PS_TYPE_C64;
     63    default:
     64        return PS_TYPE_PTR;
     65    }
     66}
     67
    2668
    2769static bool convertPsTypeToFits(psElemType type, int* bitPix, double* bZero, int* dataType)
     
    103145}
    104146
    105 static bool convertPsMetadataTypeToBinaryTForm(psMetadataType type, char** fitsType)
     147static bool convertPsTypeToBinaryTForm(psElemType type, char** fitsType)
    106148{
    107149    switch (type) {
    108     case PS_META_BOOL:
     150    case PS_TYPE_BOOL:
    109151        *fitsType = "1L";
    110152        break;
    111     case PS_META_S32:
     153    case PS_TYPE_S32:
    112154        *fitsType = "1J";
    113155        break;
    114     case PS_META_F32:
     156    case PS_TYPE_F32:
    115157        *fitsType = "1E";
    116158        break;
    117     case PS_META_F64:
     159    case PS_TYPE_F64:
    118160        *fitsType = "1D";
    119161        break;
     
    380422    char keyValue[MAX_STRING_LENGTH];
    381423    char keyComment[MAX_STRING_LENGTH];
    382     psMetadataType metadataItemType;
    383424    psBool tempBool;
    384425    psBool success;
     
    393434        switch (keyType) {
    394435        case 'I':
    395             metadataItemType = PS_META_S32;
    396             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atoi(keyValue));
     436            success = psMetadataAdd(out,
     437                                    PS_LIST_TAIL,
     438                                    keyName,
     439                                    PS_TYPE_S32,
     440                                    PS_META_PRIMITIVE,
     441                                    keyComment,
     442                                    atoi(keyValue));
    397443            break;
    398444        case 'F':
    399             metadataItemType = PS_META_F64;
    400             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atof(keyValue));
     445            success = psMetadataAdd(out,
     446                                    PS_LIST_TAIL,
     447                                    keyName,
     448                                    PS_TYPE_F64,
     449                                    PS_META_PRIMITIVE,
     450                                    keyComment,
     451                                    atof(keyValue));
    401452            break;
    402453        case 'C':
    403             metadataItemType = PS_META_STR;
    404             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, keyValue);
     454            success = psMetadataAdd(out,
     455                                    PS_LIST_TAIL,
     456                                    keyName,
     457                                    PS_TYPE_U8,
     458                                    PS_META_STR,
     459                                    keyComment,
     460                                    keyValue);
    405461            break;
    406462        case 'L':
    407             metadataItemType = PS_META_BOOL;
    408463            tempBool = (keyValue[0] == 'T') ? 1 : 0;
    409             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, tempBool);
     464            success = psMetadataAdd(out,
     465                                    PS_LIST_TAIL,
     466                                    keyName,
     467                                    PS_TYPE_BOOL,
     468                                    PS_META_PRIMITIVE,
     469                                    keyComment,
     470                                    tempBool);
    410471            break;
    411472        case 'U':
     
    530591    // write the header, if any.
    531592    if (header != NULL) {
    532         psFitsWriteHeader(fits, header);
     593        psFitsWriteHeader(header, fits);
    533594    }
    534595
     
    567628}
    568629
    569 bool psFitsWriteHeader(psMetadata* header,
     630bool psFitsWriteHeader(const psMetadata* header,
    570631                       psFits* fits)
    571632{
     
    583644    }
    584645
     646    int status = 0;
     647
     648    //transverse the metadata list and add each key.
     649
     650    psListIterator* iter = psListIteratorAlloc(header->list,PS_LIST_HEAD);
     651    psMetadataItem* item;
     652    while ( (item=psListGetNext(iter)) != NULL ) {
     653        if (item->type == PS_META_PRIMITIVE) { // we only write primitive data types.
     654            switch (item->pType) {
     655            case PS_TYPE_BOOL: {
     656                    int value = item->data.B;
     657                    fits_update_key(fits->p_fd,
     658                                    TLOGICAL,
     659                                    item->name,
     660                                    &value,
     661                                    item->comment,
     662                                    &status);
     663                    break;
     664                }
     665            case PS_TYPE_S32:
     666                fits_update_key(fits->p_fd,
     667                                TINT,
     668                                item->name,
     669                                &item->data.S32,
     670                                item->comment,
     671                                &status);
     672                break;
     673            case PS_TYPE_F32:
     674                fits_update_key(fits->p_fd,
     675                                TFLOAT,
     676                                item->name,
     677                                &item->data.F32,
     678                                item->comment,
     679                                &status);
     680                break;
     681            case PS_TYPE_F64:
     682                fits_update_key(fits->p_fd,
     683                                TDOUBLE,
     684                                item->name,
     685                                &item->data.F64,
     686                                item->comment,
     687                                &status);
     688                break;
     689            default:
     690                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     691                        PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED,
     692                        item->pType);
     693                break;
     694            }
     695        } else if (item->type == PS_META_STR) {
     696            fits_update_key(fits->p_fd,
     697                            TSTRING,
     698                            item->name,
     699                            item->data.V,
     700                            item->comment,
     701                            &status);
     702        }
     703
     704        if ( status != 0) {
     705            char fitsErr[MAX_STRING_LENGTH];
     706            (void)fits_get_errstatus(status, fitsErr);
     707            psError(PS_ERR_IO, true,
     708                    PS_ERRORTEXT_psFits_WRITE_FAILED,
     709                    fits->filename, fitsErr);
     710            return false;
     711        }
     712    }
    585713
    586714    return true;
     
    589717psMetadata* psFitsReadTableRow(psFits* fits,
    590718                               int row)
    591 {}
     719{
     720    long numRows;
     721    int numCols;
     722    int status = 0;
     723
     724    if (fits == NULL) {
     725        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     726                PS_ERRORTEXT_psFits_NULL);
     727        return NULL;
     728    }
     729
     730    // check to see if we even are positioned on a table HDU
     731    int hdutype;
     732    fits_get_hdu_type(fits->p_fd,&hdutype, &status);
     733    if ( status != 0) {
     734        char fitsErr[MAX_STRING_LENGTH];
     735        (void)fits_get_errstatus(status, fitsErr);
     736        psError(PS_ERR_IO, true,
     737                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     738                fitsErr);
     739        return NULL;
     740    }
     741    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     742        psError(PS_ERR_IO, true,
     743                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     744        return NULL;
     745    }
     746
     747    // get the size of the FITS table
     748    fits_get_num_rows(fits->p_fd, &numRows, &status);
     749    fits_get_num_cols(fits->p_fd, &numCols, &status);
     750    if ( status != 0) {
     751        char fitsErr[MAX_STRING_LENGTH];
     752        (void)fits_get_errstatus(status, fitsErr);
     753        psError(PS_ERR_IO, true,
     754                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
     755                fitsErr);
     756        return NULL;
     757    }
     758
     759    // the row parameter in the proper range?
     760    if (row < 1 || row > numRows) {
     761        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     762                PS_ERRORTEXT_psFits_ROW_INVALID,
     763                row,numRows);
     764        return NULL;
     765    }
     766
     767    psMetadata* data = psMetadataAlloc();
     768
     769    int typecode;
     770    long repeat;
     771    long width;
     772    char name[60];
     773    for (int col = 1; col <= numCols; col++) {
     774        // get the column name
     775        if (hdutype == BINARY_TBL) {
     776            fits_get_bcolparms(fits->p_fd, col, name,
     777                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
     778        } else {
     779            fits_get_acolparms(fits->p_fd, col, name,
     780                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
     781        }
     782
     783        // get the column type
     784        fits_get_coltype(fits->p_fd, col, &typecode, &repeat, &width, &status);
     785
     786        if (status == 0) {
     787
     788            #define READ_TABLE_ROW_CASE(FITSTYPE, TYPE) \
     789        case FITSTYPE: { \
     790                ps##TYPE value; \
     791                int anynul = 0; \
     792                fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
     793                              1, 1, NULL, &value, &anynul, &status); \
     794                if (anynul == 0) { \
     795                    psMetadataAdd(data,PS_LIST_TAIL, name, \
     796                                  PS_TYPE_S32, PS_META_PRIMITIVE, \
     797                                  "", value); \
     798                } \
     799            } \
     800            break;
     801
     802            switch (typecode) {
     803            case TBYTE:
     804            case TSHORT:
     805                READ_TABLE_ROW_CASE(TLONG, S32)
     806                READ_TABLE_ROW_CASE(TFLOAT, F32)
     807                READ_TABLE_ROW_CASE(TDOUBLE, F64)
     808            default:
     809                psTrace("psFits.psFitsReadTableRow", 2,
     810                        "Column %d or row %d was of a non primitive type, %d",
     811                        col, row, typecode);
     812            }
     813        }
     814
     815        if ( status != 0) {
     816            char fitsErr[MAX_STRING_LENGTH];
     817            (void)fits_get_errstatus(status, fitsErr);
     818            psError(PS_ERR_IO, true,
     819                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
     820                    col,row,fitsErr);
     821            psFree(data);
     822            return NULL;
     823        }
     824
     825    }
     826
     827    return data;
     828}
    592829
    593830psArray* psFitsReadTableColumn(psFits* fits,
    594831                               const char* colname)
    595 {}
     832{
     833    int colnum = 0;
     834    int status = 0;
     835
     836    if (fits == NULL) {
     837        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     838                PS_ERRORTEXT_psFits_NULL);
     839        return NULL;
     840    }
     841
     842    // check to see if we even are positioned on a table HDU
     843    int hdutype;
     844    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     845        char fitsErr[MAX_STRING_LENGTH];
     846        (void)fits_get_errstatus(status, fitsErr);
     847        psError(PS_ERR_IO, true,
     848                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     849                fitsErr);
     850        return NULL;
     851    }
     852    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     853        psError(PS_ERR_IO, true,
     854                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     855        return NULL;
     856    }
     857
     858    // find the column by name
     859    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     860        char fitsErr[MAX_STRING_LENGTH];
     861        (void)fits_get_errstatus(status, fitsErr);
     862        psError(PS_ERR_IO, true,
     863                PS_ERRORTEXT_psFits_FIND_COLUMN,
     864                colname, fitsErr);
     865        return NULL;
     866    }
     867
     868    // get the number of rows
     869    long numRows = 0;
     870    fits_get_num_rows(fits->p_fd, &numRows, &status);
     871
     872    psArray* result = psArrayAlloc(numRows);
     873
     874    fits_read_col_str(fits->p_fd,
     875                      colnum,
     876                      1, // firstrow
     877                      1, // firestelem
     878                      numRows,
     879                      "", // nulstr
     880                      (char**)result->data,
     881                      NULL,
     882                      &status);
     883
     884    if ( status != 0) {
     885        char fitsErr[MAX_STRING_LENGTH];
     886        (void)fits_get_errstatus(status, fitsErr);
     887        psError(PS_ERR_IO, true,
     888                PS_ERRORTEXT_psFits_TABLE_READ_COL,
     889                fitsErr);
     890        return NULL;
     891    }
     892
     893    return result;
     894}
    596895
    597896psVector* psFitsReadTableColumnNum(psFits* fits,
    598897                                   const char* colname)
    599 {}
     898{
     899    int colnum = 0;
     900    int status = 0;
     901
     902    if (fits == NULL) {
     903        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     904                PS_ERRORTEXT_psFits_NULL);
     905        return NULL;
     906    }
     907
     908    // check to see if we even are positioned on a table HDU
     909    int hdutype;
     910    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     911        char fitsErr[MAX_STRING_LENGTH];
     912        (void)fits_get_errstatus(status, fitsErr);
     913        psError(PS_ERR_IO, true,
     914                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     915                fitsErr);
     916        return NULL;
     917    }
     918    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     919        psError(PS_ERR_IO, true,
     920                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     921        return NULL;
     922    }
     923
     924    // find the column by name
     925    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     926        char fitsErr[MAX_STRING_LENGTH];
     927        (void)fits_get_errstatus(status, fitsErr);
     928        psError(PS_ERR_IO, true,
     929                PS_ERRORTEXT_psFits_FIND_COLUMN,
     930                colname, fitsErr);
     931        return NULL;
     932    }
     933
     934    // get the number of rows
     935    long numRows = 0;
     936    fits_get_num_rows(fits->p_fd, &numRows, &status);
     937
     938    // get the column datatype.
     939    int typecode;
     940    long repeat;
     941    long width;
     942    if ( fits_get_eqcoltype(fits->p_fd, colnum, &typecode, &repeat, &width, &status) != 0) {
     943        char fitsErr[MAX_STRING_LENGTH];
     944        (void)fits_get_errstatus(status, fitsErr);
     945        psError(PS_ERR_IO, true,
     946                PS_ERRORTEXT_psFits_GET_COLTYPE,
     947                fitsErr);
     948        return NULL;
     949    }
     950
     951    psVector* result = psVectorAlloc(numRows, convertFitsToPsType(typecode));
     952
     953    fits_read_col(fits->p_fd, typecode, colnum, 1 /* firstrow */,
     954                  1 /* firstelem */, numRows, NULL, result->data.V,
     955                  NULL, &status);
     956
     957    if ( status != 0) {
     958        char fitsErr[MAX_STRING_LENGTH];
     959        (void)fits_get_errstatus(status, fitsErr);
     960        psError(PS_ERR_IO, true,
     961                PS_ERRORTEXT_psFits_TABLE_READ_COL,
     962                fitsErr);
     963        return NULL;
     964    }
     965
     966    return result;
     967}
    600968
    601969
    602970psArray* psFitsReadTable(psFits* fits)
    603 {}
     971{
     972    int status = 0;
     973
     974    if (fits == NULL) {
     975        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     976                PS_ERRORTEXT_psFits_NULL);
     977        return NULL;
     978    }
     979
     980    // check to see if we even are positioned on a table HDU
     981    int hdutype;
     982    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     983        char fitsErr[MAX_STRING_LENGTH];
     984        (void)fits_get_errstatus(status, fitsErr);
     985        psError(PS_ERR_IO, true,
     986                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     987                fitsErr);
     988        return NULL;
     989    }
     990    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     991        psError(PS_ERR_IO, true,
     992                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     993        return NULL;
     994    }
     995
     996    // get the size of the FITS table
     997    long numRows = 0;
     998    int numCols = 0;
     999    fits_get_num_rows(fits->p_fd, &numRows, &status);
     1000    fits_get_num_cols(fits->p_fd, &numCols, &status);
     1001    if ( status != 0) {
     1002        char fitsErr[MAX_STRING_LENGTH];
     1003        (void)fits_get_errstatus(status, fitsErr);
     1004        psError(PS_ERR_IO, true,
     1005                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
     1006                fitsErr);
     1007        return NULL;
     1008    }
     1009
     1010    psArray* table = psArrayAlloc(numCols);
     1011
     1012    for (int row = 0; row < numRows; row++) {
     1013        table->data[row] = psFitsReadTableRow(fits,row);
     1014    }
     1015
     1016    return table;
     1017}
    6041018
    6051019bool psFitsWriteTable(psFits* fits,
    606                       psArray* table)
    607 {}
     1020                      psMetadata* header,
     1021                      psArray* table,
     1022                      char* extname)
     1023{
     1024    int status = 0;
     1025
     1026    if (fits == NULL) {
     1027        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     1028                PS_ERRORTEXT_psFits_NULL);
     1029        return NULL;
     1030    }
     1031
     1032    if (table == NULL) {
     1033        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     1034                PS_ERRORTEXT_psFits_IMAGE_NULL);
     1035        return false;
     1036    }
     1037
     1038    int rows = table->n;
     1039
     1040    // find all the columns needed
     1041    psArray* columns = psArrayAlloc(16);
     1042    columns->n=0;
     1043
     1044    // find the unique items in the array of metadata 'rows'
     1045    psMetadataItem* item;
     1046    for (int row=0; row < rows; row++) {
     1047        psMetadata* rowMeta = table->data[row];
     1048        if (rowMeta != NULL) {
     1049            psListIterator* iter = psListIteratorAlloc(rowMeta->list,
     1050                                   PS_LIST_HEAD);
     1051            while ( (item=psListGetNext(iter)) != NULL) {
     1052                if (item->type == PS_META_PRIMITIVE) {
     1053                    bool found = false;
     1054                    for (int n=0; n < columns->n && ! found; n++) {
     1055                        if (strcmp(item->name,
     1056                                   ((psMetadataItem*)(columns->data[n]))->name) == 0) {
     1057                            found = true;
     1058                        }
     1059                    }
     1060                    if (! found) {
     1061                        psArrayAdd(columns, columns->nalloc, item);
     1062                    }
     1063                }
     1064            }
     1065            psFree(iter);
     1066        }
     1067    }
     1068
     1069    if (columns->n == 0) { // no table columns found
     1070        // XXX: Error?
     1071        return false;
     1072    }
     1073
     1074    //create list of column names and types.
     1075    psArray* columnNames = psArrayAlloc(columns->n);
     1076    psArray* columnTypes = psArrayAlloc(columns->n);
     1077    for (int n=0; n < columns->n; n++) {
     1078        char* fitsType;
     1079        columnNames->data[n] = ((psMetadataItem*)columns->data[n])->name;
     1080        if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
     1081                                          &fitsType)) {
     1082            // XXX: error message
     1083            return false;
     1084        }
     1085        columnTypes->data[n] = fitsType;
     1086    }
     1087
     1088    fits_create_tbl(fits->p_fd,
     1089                    BINARY_TBL,
     1090                    table->n, // number of rows in table
     1091                    columns->n, // number of columns in table
     1092                    (char**)columnNames->data, // names of the columns
     1093                    (char**)columnTypes->data, // format of the columns
     1094                    NULL, // physical unit of columns
     1095                    extname, // extension name
     1096                    &status);
     1097
     1098    // fill in the table elements with data
     1099    for (int n = 0; n < columns->n; n++) {
     1100        int row;
     1101        item = columns->data[n];
     1102        psArray* columnItems = psArrayAlloc(table->n);
     1103        for (row = 0; row < table->n; row++) {
     1104            columnItems->data[row] = psMetadataLookup(table->data[row],item->name);
     1105        }
     1106
     1107        if (item->type == PS_META_PRIMITIVE) {
     1108            psVector* col = psVectorAlloc(table->n, item->pType);
     1109            switch (item->pType) {
     1110            case PS_TYPE_S32:
     1111                for (row = 0; row < table->n; row++) {
     1112                    col->data.S32[row] = item->data.S32;
     1113                }
     1114                fits_write_col_int(fits->p_fd,
     1115                                   n, // column number
     1116                                   1, // firstrow
     1117                                   1, // firstelem
     1118                                   table->n, // nelements
     1119                                   col->data.S32,
     1120                                   &status);
     1121                break;
     1122            case PS_TYPE_F32:
     1123                for (row = 0; row < table->n; row++) {
     1124                    col->data.F32[row] = item->data.F32;
     1125                }
     1126                fits_write_col_flt(fits->p_fd,
     1127                                   n, // column number
     1128                                   1, // firstrow
     1129                                   1, // firstelem
     1130                                   table->n, // nelements
     1131                                   col->data.F32,
     1132                                   &status);
     1133                break;
     1134            case PS_TYPE_S64:
     1135                for (row = 0; row < table->n; row++) {
     1136                    col->data.F64[row] = item->data.F64;
     1137                }
     1138                fits_write_col_dbl(fits->p_fd,
     1139                                   n, // column number
     1140                                   1, // firstrow
     1141                                   1, // firstelem
     1142                                   table->n, // nelements
     1143                                   col->data.F64,
     1144                                   &status);
     1145                break;
     1146            default:
     1147                // XXX: error message
     1148                psFree(col);
     1149                psFree(columnItems);
     1150                psFree(columnNames);
     1151                psFree(columnTypes);
     1152                psFree(columns);
     1153                return false;
     1154            }
     1155
     1156        } else if (item->type == PS_META_STR) {
     1157            psArray* col = psArrayAlloc(table->n);
     1158            for (row = 0; row < table->n; row++) {
     1159                col->data[row] = item->data.V;
     1160            }
     1161            fits_write_col_str(fits->p_fd,
     1162                               n, // column number
     1163                               1, // firstrow
     1164                               1, // firstelem
     1165                               table->n, // nelements
     1166                               (char**)col->data,
     1167                               &status);
     1168        }
     1169    }
     1170
     1171    return true;
     1172}
  • trunk/psLib/src/dataIO/psFits.h

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    143143 */
    144144bool psFitsWriteHeader(
    145     psMetadata* header,                ///< the psMetadata data in which to write
     145    const psMetadata* header,          ///< the psMetadata data in which to write
    146146    psFits* fits                       ///< the psFits object
    147147);
     
    162162 *  @return bool        TRUE is the write was successful, otherwise FALSE.
    163163 */
    164 bool psFitsWriteImageSection(
    165     psFits* fits,                      ///< the psFits object
     164bool psFitsWriteImage(
     165    psFits* fits,                      ///< the psFits object
     166    const psMetadata* header,
    166167    const psImage* input,              ///< the image to output
    167     psRegion region,                   ///< the part of the FITS image to overwrite
    168     int z                              ///< the z-plane of the FITS image data cube to use
     168    int depth                          ///< the number of z-planes of the FITS image data cube
    169169);
    170170
     
    223223bool psFitsWriteTable(
    224224    psFits* fits,                      ///< the psFits object
    225     psArray* table
     225    psMetadata* header,
     226    psArray* table,
    226227    ///< Array of psMetadata items, which contains the output data items of each row.
     228    char* extname
    227229);
    228230
  • trunk/psLib/src/fileUtils/psFileUtilsErrors.dat

    r2681 r2806  
    2525psFits_GETHDUTYPE_FAILED               Failed to determine an HDU type in file %s.\nCFITSIO Error: %s
    2626psFits_GETNUMKEYS_FAILED               Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s
     27psFits_GET_TABLE_SIZE_FAILED           Failed to determine the size of the current HDU table.\nCFITSIO Error: %s
    2728psFits_FILENAME_CREATE_FAILED          Could not create file,'%s'.\nCFITSIO Error: %s
    2829psFits_TYPE_UNSUPPORTED                Specified type, %s, is not supported.
    2930psFits_CREATE_HDU_FAILED               Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s
    30 psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an IMAGE.
     31psFits_GET_HDU_TYPE_FAILED             Could not determine the HDU type.\nCFITSIO Error: %s
     32psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an image.
     33psFits_NOT_TABLE_TYPE                  Current FITS HDU type must be a table.
    3134psFits_TABLE_FIRSTROW_NULL             Can't create a table without the first row, where table column information is derived.
    3235psFits_CFITSIO_ERROR                   CFITSIO error: %s
    3336psFits_METATYPE_INVALID                Specified FITS metadata type, %c, is not supported.
    3437psFits_METADATA_ADD_FAILED             Failed to add metadata item, %s.
    35 psFits_WRITE_FAILED                    Could not write psImage data to file,'%s'.\nCFITSIO Error: %s
     38psFits_WRITE_FAILED                    Could not write data to file,'%s'.\nCFITSIO Error: %s
    3639psFits_IMAGE_NULL                      The input psImage was NULL.  Need a non-NULL psImage for operation to be performed.
    3740psFits_METADATA_NULL                   The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed.
     41psFits_METADATA_PTYPE_UNSUPPORTED      A metadata item's primative type, %d, is not supported.
     42psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows. 
     43psFits_GET_TABLE_ELEMENT               Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s
     44psFits_FIND_COLUMN                     Specified column, %s, was not found.\nCFITSIO Error: %s
     45psFits_GET_COLTYPE                     Could not determine the datatype of the table column.\nCFITSIO Error: %s
     46psFits_TABLE_READ_COL                  Failed to read table column.\nCFITSIO Error: %s
    3847#
  • trunk/psLib/src/fileUtils/psFileUtilsErrors.h

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    4747#define PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED "Failed to determine an HDU type in file %s.\nCFITSIO Error: %s"
    4848#define PS_ERRORTEXT_psFits_GETNUMKEYS_FAILED "Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s"
     49#define PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED "Failed to determine the size of the current HDU table.\nCFITSIO Error: %s"
    4950#define PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED "Could not create file,'%s'.\nCFITSIO Error: %s"
    5051#define PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED "Specified type, %s, is not supported."
    5152#define PS_ERRORTEXT_psFits_CREATE_HDU_FAILED "Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s"
    52 #define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an IMAGE."
     53#define PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED "Could not determine the HDU type.\nCFITSIO Error: %s"
     54#define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an image."
     55#define PS_ERRORTEXT_psFits_NOT_TABLE_TYPE "Current FITS HDU type must be a table."
    5356#define PS_ERRORTEXT_psFits_TABLE_FIRSTROW_NULL "Can't create a table without the first row, where table column information is derived."
    5457#define PS_ERRORTEXT_psFits_CFITSIO_ERROR "CFITSIO error: %s"
    5558#define PS_ERRORTEXT_psFits_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."
    5659#define PS_ERRORTEXT_psFits_METADATA_ADD_FAILED "Failed to add metadata item, %s."
    57 #define PS_ERRORTEXT_psFits_WRITE_FAILED "Could not write psImage data to file,'%s'.\nCFITSIO Error: %s"
     60#define PS_ERRORTEXT_psFits_WRITE_FAILED "Could not write data to file,'%s'.\nCFITSIO Error: %s"
    5861#define PS_ERRORTEXT_psFits_IMAGE_NULL "The input psImage was NULL.  Need a non-NULL psImage for operation to be performed."
    5962#define PS_ERRORTEXT_psFits_METADATA_NULL "The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed."
     63#define PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED "A metadata item's primative type, %d, is not supported."
     64#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows.  "
     65#define PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT "Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s"
     66#define PS_ERRORTEXT_psFits_FIND_COLUMN "Specified column, %s, was not found.\nCFITSIO Error: %s"
     67#define PS_ERRORTEXT_psFits_GET_COLTYPE "Could not determine the datatype of the table column.\nCFITSIO Error: %s"
     68#define PS_ERRORTEXT_psFits_TABLE_READ_COL "Failed to read table column.\nCFITSIO Error: %s"
    6069//~End
    6170
  • trunk/psLib/src/fileUtils/psFits.c

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2222#include "psString.h"
    2323#include "psLogMsg.h"
     24#include "psTrace.h"
    2425
    2526#define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
     27
     28static psElemType convertFitsToPsType(int datatype)
     29{
     30    switch (datatype) {
     31    case TBYTE:
     32        return PS_TYPE_U8;
     33    case TSBYTE:
     34        return PS_TYPE_S8;
     35    case TSHORT:
     36        return PS_TYPE_S16;
     37    case TUSHORT:
     38        return PS_TYPE_U16;
     39    case TLONG:
     40        if (sizeof(long) == 8) {
     41            return PS_TYPE_S64;
     42        }
     43        // no break
     44    case TINT:
     45        return PS_TYPE_S32;
     46    case TULONG:
     47        if (sizeof(unsigned long) == 8) {
     48            return PS_TYPE_U64;
     49        }
     50        // no break
     51    case TUINT:
     52        return PS_TYPE_U32;
     53    case TLONGLONG:
     54        return PS_TYPE_S64;
     55    case TFLOAT:
     56        return PS_TYPE_F32;
     57    case TDOUBLE:
     58        return PS_TYPE_F64;
     59    case TCOMPLEX:
     60        return PS_TYPE_C32;
     61    case TDBLCOMPLEX:
     62        return PS_TYPE_C64;
     63    default:
     64        return PS_TYPE_PTR;
     65    }
     66}
     67
    2668
    2769static bool convertPsTypeToFits(psElemType type, int* bitPix, double* bZero, int* dataType)
     
    103145}
    104146
    105 static bool convertPsMetadataTypeToBinaryTForm(psMetadataType type, char** fitsType)
     147static bool convertPsTypeToBinaryTForm(psElemType type, char** fitsType)
    106148{
    107149    switch (type) {
    108     case PS_META_BOOL:
     150    case PS_TYPE_BOOL:
    109151        *fitsType = "1L";
    110152        break;
    111     case PS_META_S32:
     153    case PS_TYPE_S32:
    112154        *fitsType = "1J";
    113155        break;
    114     case PS_META_F32:
     156    case PS_TYPE_F32:
    115157        *fitsType = "1E";
    116158        break;
    117     case PS_META_F64:
     159    case PS_TYPE_F64:
    118160        *fitsType = "1D";
    119161        break;
     
    380422    char keyValue[MAX_STRING_LENGTH];
    381423    char keyComment[MAX_STRING_LENGTH];
    382     psMetadataType metadataItemType;
    383424    psBool tempBool;
    384425    psBool success;
     
    393434        switch (keyType) {
    394435        case 'I':
    395             metadataItemType = PS_META_S32;
    396             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atoi(keyValue));
     436            success = psMetadataAdd(out,
     437                                    PS_LIST_TAIL,
     438                                    keyName,
     439                                    PS_TYPE_S32,
     440                                    PS_META_PRIMITIVE,
     441                                    keyComment,
     442                                    atoi(keyValue));
    397443            break;
    398444        case 'F':
    399             metadataItemType = PS_META_F64;
    400             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atof(keyValue));
     445            success = psMetadataAdd(out,
     446                                    PS_LIST_TAIL,
     447                                    keyName,
     448                                    PS_TYPE_F64,
     449                                    PS_META_PRIMITIVE,
     450                                    keyComment,
     451                                    atof(keyValue));
    401452            break;
    402453        case 'C':
    403             metadataItemType = PS_META_STR;
    404             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, keyValue);
     454            success = psMetadataAdd(out,
     455                                    PS_LIST_TAIL,
     456                                    keyName,
     457                                    PS_TYPE_U8,
     458                                    PS_META_STR,
     459                                    keyComment,
     460                                    keyValue);
    405461            break;
    406462        case 'L':
    407             metadataItemType = PS_META_BOOL;
    408463            tempBool = (keyValue[0] == 'T') ? 1 : 0;
    409             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, tempBool);
     464            success = psMetadataAdd(out,
     465                                    PS_LIST_TAIL,
     466                                    keyName,
     467                                    PS_TYPE_BOOL,
     468                                    PS_META_PRIMITIVE,
     469                                    keyComment,
     470                                    tempBool);
    410471            break;
    411472        case 'U':
     
    530591    // write the header, if any.
    531592    if (header != NULL) {
    532         psFitsWriteHeader(fits, header);
     593        psFitsWriteHeader(header, fits);
    533594    }
    534595
     
    567628}
    568629
    569 bool psFitsWriteHeader(psMetadata* header,
     630bool psFitsWriteHeader(const psMetadata* header,
    570631                       psFits* fits)
    571632{
     
    583644    }
    584645
     646    int status = 0;
     647
     648    //transverse the metadata list and add each key.
     649
     650    psListIterator* iter = psListIteratorAlloc(header->list,PS_LIST_HEAD);
     651    psMetadataItem* item;
     652    while ( (item=psListGetNext(iter)) != NULL ) {
     653        if (item->type == PS_META_PRIMITIVE) { // we only write primitive data types.
     654            switch (item->pType) {
     655            case PS_TYPE_BOOL: {
     656                    int value = item->data.B;
     657                    fits_update_key(fits->p_fd,
     658                                    TLOGICAL,
     659                                    item->name,
     660                                    &value,
     661                                    item->comment,
     662                                    &status);
     663                    break;
     664                }
     665            case PS_TYPE_S32:
     666                fits_update_key(fits->p_fd,
     667                                TINT,
     668                                item->name,
     669                                &item->data.S32,
     670                                item->comment,
     671                                &status);
     672                break;
     673            case PS_TYPE_F32:
     674                fits_update_key(fits->p_fd,
     675                                TFLOAT,
     676                                item->name,
     677                                &item->data.F32,
     678                                item->comment,
     679                                &status);
     680                break;
     681            case PS_TYPE_F64:
     682                fits_update_key(fits->p_fd,
     683                                TDOUBLE,
     684                                item->name,
     685                                &item->data.F64,
     686                                item->comment,
     687                                &status);
     688                break;
     689            default:
     690                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     691                        PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED,
     692                        item->pType);
     693                break;
     694            }
     695        } else if (item->type == PS_META_STR) {
     696            fits_update_key(fits->p_fd,
     697                            TSTRING,
     698                            item->name,
     699                            item->data.V,
     700                            item->comment,
     701                            &status);
     702        }
     703
     704        if ( status != 0) {
     705            char fitsErr[MAX_STRING_LENGTH];
     706            (void)fits_get_errstatus(status, fitsErr);
     707            psError(PS_ERR_IO, true,
     708                    PS_ERRORTEXT_psFits_WRITE_FAILED,
     709                    fits->filename, fitsErr);
     710            return false;
     711        }
     712    }
    585713
    586714    return true;
     
    589717psMetadata* psFitsReadTableRow(psFits* fits,
    590718                               int row)
    591 {}
     719{
     720    long numRows;
     721    int numCols;
     722    int status = 0;
     723
     724    if (fits == NULL) {
     725        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     726                PS_ERRORTEXT_psFits_NULL);
     727        return NULL;
     728    }
     729
     730    // check to see if we even are positioned on a table HDU
     731    int hdutype;
     732    fits_get_hdu_type(fits->p_fd,&hdutype, &status);
     733    if ( status != 0) {
     734        char fitsErr[MAX_STRING_LENGTH];
     735        (void)fits_get_errstatus(status, fitsErr);
     736        psError(PS_ERR_IO, true,
     737                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     738                fitsErr);
     739        return NULL;
     740    }
     741    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     742        psError(PS_ERR_IO, true,
     743                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     744        return NULL;
     745    }
     746
     747    // get the size of the FITS table
     748    fits_get_num_rows(fits->p_fd, &numRows, &status);
     749    fits_get_num_cols(fits->p_fd, &numCols, &status);
     750    if ( status != 0) {
     751        char fitsErr[MAX_STRING_LENGTH];
     752        (void)fits_get_errstatus(status, fitsErr);
     753        psError(PS_ERR_IO, true,
     754                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
     755                fitsErr);
     756        return NULL;
     757    }
     758
     759    // the row parameter in the proper range?
     760    if (row < 1 || row > numRows) {
     761        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     762                PS_ERRORTEXT_psFits_ROW_INVALID,
     763                row,numRows);
     764        return NULL;
     765    }
     766
     767    psMetadata* data = psMetadataAlloc();
     768
     769    int typecode;
     770    long repeat;
     771    long width;
     772    char name[60];
     773    for (int col = 1; col <= numCols; col++) {
     774        // get the column name
     775        if (hdutype == BINARY_TBL) {
     776            fits_get_bcolparms(fits->p_fd, col, name,
     777                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
     778        } else {
     779            fits_get_acolparms(fits->p_fd, col, name,
     780                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
     781        }
     782
     783        // get the column type
     784        fits_get_coltype(fits->p_fd, col, &typecode, &repeat, &width, &status);
     785
     786        if (status == 0) {
     787
     788            #define READ_TABLE_ROW_CASE(FITSTYPE, TYPE) \
     789        case FITSTYPE: { \
     790                ps##TYPE value; \
     791                int anynul = 0; \
     792                fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
     793                              1, 1, NULL, &value, &anynul, &status); \
     794                if (anynul == 0) { \
     795                    psMetadataAdd(data,PS_LIST_TAIL, name, \
     796                                  PS_TYPE_S32, PS_META_PRIMITIVE, \
     797                                  "", value); \
     798                } \
     799            } \
     800            break;
     801
     802            switch (typecode) {
     803            case TBYTE:
     804            case TSHORT:
     805                READ_TABLE_ROW_CASE(TLONG, S32)
     806                READ_TABLE_ROW_CASE(TFLOAT, F32)
     807                READ_TABLE_ROW_CASE(TDOUBLE, F64)
     808            default:
     809                psTrace("psFits.psFitsReadTableRow", 2,
     810                        "Column %d or row %d was of a non primitive type, %d",
     811                        col, row, typecode);
     812            }
     813        }
     814
     815        if ( status != 0) {
     816            char fitsErr[MAX_STRING_LENGTH];
     817            (void)fits_get_errstatus(status, fitsErr);
     818            psError(PS_ERR_IO, true,
     819                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
     820                    col,row,fitsErr);
     821            psFree(data);
     822            return NULL;
     823        }
     824
     825    }
     826
     827    return data;
     828}
    592829
    593830psArray* psFitsReadTableColumn(psFits* fits,
    594831                               const char* colname)
    595 {}
     832{
     833    int colnum = 0;
     834    int status = 0;
     835
     836    if (fits == NULL) {
     837        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     838                PS_ERRORTEXT_psFits_NULL);
     839        return NULL;
     840    }
     841
     842    // check to see if we even are positioned on a table HDU
     843    int hdutype;
     844    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     845        char fitsErr[MAX_STRING_LENGTH];
     846        (void)fits_get_errstatus(status, fitsErr);
     847        psError(PS_ERR_IO, true,
     848                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     849                fitsErr);
     850        return NULL;
     851    }
     852    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     853        psError(PS_ERR_IO, true,
     854                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     855        return NULL;
     856    }
     857
     858    // find the column by name
     859    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     860        char fitsErr[MAX_STRING_LENGTH];
     861        (void)fits_get_errstatus(status, fitsErr);
     862        psError(PS_ERR_IO, true,
     863                PS_ERRORTEXT_psFits_FIND_COLUMN,
     864                colname, fitsErr);
     865        return NULL;
     866    }
     867
     868    // get the number of rows
     869    long numRows = 0;
     870    fits_get_num_rows(fits->p_fd, &numRows, &status);
     871
     872    psArray* result = psArrayAlloc(numRows);
     873
     874    fits_read_col_str(fits->p_fd,
     875                      colnum,
     876                      1, // firstrow
     877                      1, // firestelem
     878                      numRows,
     879                      "", // nulstr
     880                      (char**)result->data,
     881                      NULL,
     882                      &status);
     883
     884    if ( status != 0) {
     885        char fitsErr[MAX_STRING_LENGTH];
     886        (void)fits_get_errstatus(status, fitsErr);
     887        psError(PS_ERR_IO, true,
     888                PS_ERRORTEXT_psFits_TABLE_READ_COL,
     889                fitsErr);
     890        return NULL;
     891    }
     892
     893    return result;
     894}
    596895
    597896psVector* psFitsReadTableColumnNum(psFits* fits,
    598897                                   const char* colname)
    599 {}
     898{
     899    int colnum = 0;
     900    int status = 0;
     901
     902    if (fits == NULL) {
     903        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     904                PS_ERRORTEXT_psFits_NULL);
     905        return NULL;
     906    }
     907
     908    // check to see if we even are positioned on a table HDU
     909    int hdutype;
     910    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     911        char fitsErr[MAX_STRING_LENGTH];
     912        (void)fits_get_errstatus(status, fitsErr);
     913        psError(PS_ERR_IO, true,
     914                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     915                fitsErr);
     916        return NULL;
     917    }
     918    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     919        psError(PS_ERR_IO, true,
     920                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     921        return NULL;
     922    }
     923
     924    // find the column by name
     925    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     926        char fitsErr[MAX_STRING_LENGTH];
     927        (void)fits_get_errstatus(status, fitsErr);
     928        psError(PS_ERR_IO, true,
     929                PS_ERRORTEXT_psFits_FIND_COLUMN,
     930                colname, fitsErr);
     931        return NULL;
     932    }
     933
     934    // get the number of rows
     935    long numRows = 0;
     936    fits_get_num_rows(fits->p_fd, &numRows, &status);
     937
     938    // get the column datatype.
     939    int typecode;
     940    long repeat;
     941    long width;
     942    if ( fits_get_eqcoltype(fits->p_fd, colnum, &typecode, &repeat, &width, &status) != 0) {
     943        char fitsErr[MAX_STRING_LENGTH];
     944        (void)fits_get_errstatus(status, fitsErr);
     945        psError(PS_ERR_IO, true,
     946                PS_ERRORTEXT_psFits_GET_COLTYPE,
     947                fitsErr);
     948        return NULL;
     949    }
     950
     951    psVector* result = psVectorAlloc(numRows, convertFitsToPsType(typecode));
     952
     953    fits_read_col(fits->p_fd, typecode, colnum, 1 /* firstrow */,
     954                  1 /* firstelem */, numRows, NULL, result->data.V,
     955                  NULL, &status);
     956
     957    if ( status != 0) {
     958        char fitsErr[MAX_STRING_LENGTH];
     959        (void)fits_get_errstatus(status, fitsErr);
     960        psError(PS_ERR_IO, true,
     961                PS_ERRORTEXT_psFits_TABLE_READ_COL,
     962                fitsErr);
     963        return NULL;
     964    }
     965
     966    return result;
     967}
    600968
    601969
    602970psArray* psFitsReadTable(psFits* fits)
    603 {}
     971{
     972    int status = 0;
     973
     974    if (fits == NULL) {
     975        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     976                PS_ERRORTEXT_psFits_NULL);
     977        return NULL;
     978    }
     979
     980    // check to see if we even are positioned on a table HDU
     981    int hdutype;
     982    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     983        char fitsErr[MAX_STRING_LENGTH];
     984        (void)fits_get_errstatus(status, fitsErr);
     985        psError(PS_ERR_IO, true,
     986                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     987                fitsErr);
     988        return NULL;
     989    }
     990    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     991        psError(PS_ERR_IO, true,
     992                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     993        return NULL;
     994    }
     995
     996    // get the size of the FITS table
     997    long numRows = 0;
     998    int numCols = 0;
     999    fits_get_num_rows(fits->p_fd, &numRows, &status);
     1000    fits_get_num_cols(fits->p_fd, &numCols, &status);
     1001    if ( status != 0) {
     1002        char fitsErr[MAX_STRING_LENGTH];
     1003        (void)fits_get_errstatus(status, fitsErr);
     1004        psError(PS_ERR_IO, true,
     1005                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
     1006                fitsErr);
     1007        return NULL;
     1008    }
     1009
     1010    psArray* table = psArrayAlloc(numCols);
     1011
     1012    for (int row = 0; row < numRows; row++) {
     1013        table->data[row] = psFitsReadTableRow(fits,row);
     1014    }
     1015
     1016    return table;
     1017}
    6041018
    6051019bool psFitsWriteTable(psFits* fits,
    606                       psArray* table)
    607 {}
     1020                      psMetadata* header,
     1021                      psArray* table,
     1022                      char* extname)
     1023{
     1024    int status = 0;
     1025
     1026    if (fits == NULL) {
     1027        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     1028                PS_ERRORTEXT_psFits_NULL);
     1029        return NULL;
     1030    }
     1031
     1032    if (table == NULL) {
     1033        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     1034                PS_ERRORTEXT_psFits_IMAGE_NULL);
     1035        return false;
     1036    }
     1037
     1038    int rows = table->n;
     1039
     1040    // find all the columns needed
     1041    psArray* columns = psArrayAlloc(16);
     1042    columns->n=0;
     1043
     1044    // find the unique items in the array of metadata 'rows'
     1045    psMetadataItem* item;
     1046    for (int row=0; row < rows; row++) {
     1047        psMetadata* rowMeta = table->data[row];
     1048        if (rowMeta != NULL) {
     1049            psListIterator* iter = psListIteratorAlloc(rowMeta->list,
     1050                                   PS_LIST_HEAD);
     1051            while ( (item=psListGetNext(iter)) != NULL) {
     1052                if (item->type == PS_META_PRIMITIVE) {
     1053                    bool found = false;
     1054                    for (int n=0; n < columns->n && ! found; n++) {
     1055                        if (strcmp(item->name,
     1056                                   ((psMetadataItem*)(columns->data[n]))->name) == 0) {
     1057                            found = true;
     1058                        }
     1059                    }
     1060                    if (! found) {
     1061                        psArrayAdd(columns, columns->nalloc, item);
     1062                    }
     1063                }
     1064            }
     1065            psFree(iter);
     1066        }
     1067    }
     1068
     1069    if (columns->n == 0) { // no table columns found
     1070        // XXX: Error?
     1071        return false;
     1072    }
     1073
     1074    //create list of column names and types.
     1075    psArray* columnNames = psArrayAlloc(columns->n);
     1076    psArray* columnTypes = psArrayAlloc(columns->n);
     1077    for (int n=0; n < columns->n; n++) {
     1078        char* fitsType;
     1079        columnNames->data[n] = ((psMetadataItem*)columns->data[n])->name;
     1080        if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
     1081                                          &fitsType)) {
     1082            // XXX: error message
     1083            return false;
     1084        }
     1085        columnTypes->data[n] = fitsType;
     1086    }
     1087
     1088    fits_create_tbl(fits->p_fd,
     1089                    BINARY_TBL,
     1090                    table->n, // number of rows in table
     1091                    columns->n, // number of columns in table
     1092                    (char**)columnNames->data, // names of the columns
     1093                    (char**)columnTypes->data, // format of the columns
     1094                    NULL, // physical unit of columns
     1095                    extname, // extension name
     1096                    &status);
     1097
     1098    // fill in the table elements with data
     1099    for (int n = 0; n < columns->n; n++) {
     1100        int row;
     1101        item = columns->data[n];
     1102        psArray* columnItems = psArrayAlloc(table->n);
     1103        for (row = 0; row < table->n; row++) {
     1104            columnItems->data[row] = psMetadataLookup(table->data[row],item->name);
     1105        }
     1106
     1107        if (item->type == PS_META_PRIMITIVE) {
     1108            psVector* col = psVectorAlloc(table->n, item->pType);
     1109            switch (item->pType) {
     1110            case PS_TYPE_S32:
     1111                for (row = 0; row < table->n; row++) {
     1112                    col->data.S32[row] = item->data.S32;
     1113                }
     1114                fits_write_col_int(fits->p_fd,
     1115                                   n, // column number
     1116                                   1, // firstrow
     1117                                   1, // firstelem
     1118                                   table->n, // nelements
     1119                                   col->data.S32,
     1120                                   &status);
     1121                break;
     1122            case PS_TYPE_F32:
     1123                for (row = 0; row < table->n; row++) {
     1124                    col->data.F32[row] = item->data.F32;
     1125                }
     1126                fits_write_col_flt(fits->p_fd,
     1127                                   n, // column number
     1128                                   1, // firstrow
     1129                                   1, // firstelem
     1130                                   table->n, // nelements
     1131                                   col->data.F32,
     1132                                   &status);
     1133                break;
     1134            case PS_TYPE_S64:
     1135                for (row = 0; row < table->n; row++) {
     1136                    col->data.F64[row] = item->data.F64;
     1137                }
     1138                fits_write_col_dbl(fits->p_fd,
     1139                                   n, // column number
     1140                                   1, // firstrow
     1141                                   1, // firstelem
     1142                                   table->n, // nelements
     1143                                   col->data.F64,
     1144                                   &status);
     1145                break;
     1146            default:
     1147                // XXX: error message
     1148                psFree(col);
     1149                psFree(columnItems);
     1150                psFree(columnNames);
     1151                psFree(columnTypes);
     1152                psFree(columns);
     1153                return false;
     1154            }
     1155
     1156        } else if (item->type == PS_META_STR) {
     1157            psArray* col = psArrayAlloc(table->n);
     1158            for (row = 0; row < table->n; row++) {
     1159                col->data[row] = item->data.V;
     1160            }
     1161            fits_write_col_str(fits->p_fd,
     1162                               n, // column number
     1163                               1, // firstrow
     1164                               1, // firstelem
     1165                               table->n, // nelements
     1166                               (char**)col->data,
     1167                               &status);
     1168        }
     1169    }
     1170
     1171    return true;
     1172}
  • trunk/psLib/src/fileUtils/psFits.h

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    143143 */
    144144bool psFitsWriteHeader(
    145     psMetadata* header,                ///< the psMetadata data in which to write
     145    const psMetadata* header,          ///< the psMetadata data in which to write
    146146    psFits* fits                       ///< the psFits object
    147147);
     
    162162 *  @return bool        TRUE is the write was successful, otherwise FALSE.
    163163 */
    164 bool psFitsWriteImageSection(
    165     psFits* fits,                      ///< the psFits object
     164bool psFitsWriteImage(
     165    psFits* fits,                      ///< the psFits object
     166    const psMetadata* header,
    166167    const psImage* input,              ///< the image to output
    167     psRegion region,                   ///< the part of the FITS image to overwrite
    168     int z                              ///< the z-plane of the FITS image data cube to use
     168    int depth                          ///< the number of z-planes of the FITS image data cube
    169169);
    170170
     
    223223bool psFitsWriteTable(
    224224    psFits* fits,                      ///< the psFits object
    225     psArray* table
     225    psMetadata* header,
     226    psArray* table,
    226227    ///< Array of psMetadata items, which contains the output data items of each row.
     228    char* extname
    227229);
    228230
  • trunk/psLib/src/fits/psFits.c

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2222#include "psString.h"
    2323#include "psLogMsg.h"
     24#include "psTrace.h"
    2425
    2526#define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
     27
     28static psElemType convertFitsToPsType(int datatype)
     29{
     30    switch (datatype) {
     31    case TBYTE:
     32        return PS_TYPE_U8;
     33    case TSBYTE:
     34        return PS_TYPE_S8;
     35    case TSHORT:
     36        return PS_TYPE_S16;
     37    case TUSHORT:
     38        return PS_TYPE_U16;
     39    case TLONG:
     40        if (sizeof(long) == 8) {
     41            return PS_TYPE_S64;
     42        }
     43        // no break
     44    case TINT:
     45        return PS_TYPE_S32;
     46    case TULONG:
     47        if (sizeof(unsigned long) == 8) {
     48            return PS_TYPE_U64;
     49        }
     50        // no break
     51    case TUINT:
     52        return PS_TYPE_U32;
     53    case TLONGLONG:
     54        return PS_TYPE_S64;
     55    case TFLOAT:
     56        return PS_TYPE_F32;
     57    case TDOUBLE:
     58        return PS_TYPE_F64;
     59    case TCOMPLEX:
     60        return PS_TYPE_C32;
     61    case TDBLCOMPLEX:
     62        return PS_TYPE_C64;
     63    default:
     64        return PS_TYPE_PTR;
     65    }
     66}
     67
    2668
    2769static bool convertPsTypeToFits(psElemType type, int* bitPix, double* bZero, int* dataType)
     
    103145}
    104146
    105 static bool convertPsMetadataTypeToBinaryTForm(psMetadataType type, char** fitsType)
     147static bool convertPsTypeToBinaryTForm(psElemType type, char** fitsType)
    106148{
    107149    switch (type) {
    108     case PS_META_BOOL:
     150    case PS_TYPE_BOOL:
    109151        *fitsType = "1L";
    110152        break;
    111     case PS_META_S32:
     153    case PS_TYPE_S32:
    112154        *fitsType = "1J";
    113155        break;
    114     case PS_META_F32:
     156    case PS_TYPE_F32:
    115157        *fitsType = "1E";
    116158        break;
    117     case PS_META_F64:
     159    case PS_TYPE_F64:
    118160        *fitsType = "1D";
    119161        break;
     
    380422    char keyValue[MAX_STRING_LENGTH];
    381423    char keyComment[MAX_STRING_LENGTH];
    382     psMetadataType metadataItemType;
    383424    psBool tempBool;
    384425    psBool success;
     
    393434        switch (keyType) {
    394435        case 'I':
    395             metadataItemType = PS_META_S32;
    396             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atoi(keyValue));
     436            success = psMetadataAdd(out,
     437                                    PS_LIST_TAIL,
     438                                    keyName,
     439                                    PS_TYPE_S32,
     440                                    PS_META_PRIMITIVE,
     441                                    keyComment,
     442                                    atoi(keyValue));
    397443            break;
    398444        case 'F':
    399             metadataItemType = PS_META_F64;
    400             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atof(keyValue));
     445            success = psMetadataAdd(out,
     446                                    PS_LIST_TAIL,
     447                                    keyName,
     448                                    PS_TYPE_F64,
     449                                    PS_META_PRIMITIVE,
     450                                    keyComment,
     451                                    atof(keyValue));
    401452            break;
    402453        case 'C':
    403             metadataItemType = PS_META_STR;
    404             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, keyValue);
     454            success = psMetadataAdd(out,
     455                                    PS_LIST_TAIL,
     456                                    keyName,
     457                                    PS_TYPE_U8,
     458                                    PS_META_STR,
     459                                    keyComment,
     460                                    keyValue);
    405461            break;
    406462        case 'L':
    407             metadataItemType = PS_META_BOOL;
    408463            tempBool = (keyValue[0] == 'T') ? 1 : 0;
    409             success = psMetadataAdd(out, PS_LIST_TAIL, keyName, metadataItemType, keyComment, tempBool);
     464            success = psMetadataAdd(out,
     465                                    PS_LIST_TAIL,
     466                                    keyName,
     467                                    PS_TYPE_BOOL,
     468                                    PS_META_PRIMITIVE,
     469                                    keyComment,
     470                                    tempBool);
    410471            break;
    411472        case 'U':
     
    530591    // write the header, if any.
    531592    if (header != NULL) {
    532         psFitsWriteHeader(fits, header);
     593        psFitsWriteHeader(header, fits);
    533594    }
    534595
     
    567628}
    568629
    569 bool psFitsWriteHeader(psMetadata* header,
     630bool psFitsWriteHeader(const psMetadata* header,
    570631                       psFits* fits)
    571632{
     
    583644    }
    584645
     646    int status = 0;
     647
     648    //transverse the metadata list and add each key.
     649
     650    psListIterator* iter = psListIteratorAlloc(header->list,PS_LIST_HEAD);
     651    psMetadataItem* item;
     652    while ( (item=psListGetNext(iter)) != NULL ) {
     653        if (item->type == PS_META_PRIMITIVE) { // we only write primitive data types.
     654            switch (item->pType) {
     655            case PS_TYPE_BOOL: {
     656                    int value = item->data.B;
     657                    fits_update_key(fits->p_fd,
     658                                    TLOGICAL,
     659                                    item->name,
     660                                    &value,
     661                                    item->comment,
     662                                    &status);
     663                    break;
     664                }
     665            case PS_TYPE_S32:
     666                fits_update_key(fits->p_fd,
     667                                TINT,
     668                                item->name,
     669                                &item->data.S32,
     670                                item->comment,
     671                                &status);
     672                break;
     673            case PS_TYPE_F32:
     674                fits_update_key(fits->p_fd,
     675                                TFLOAT,
     676                                item->name,
     677                                &item->data.F32,
     678                                item->comment,
     679                                &status);
     680                break;
     681            case PS_TYPE_F64:
     682                fits_update_key(fits->p_fd,
     683                                TDOUBLE,
     684                                item->name,
     685                                &item->data.F64,
     686                                item->comment,
     687                                &status);
     688                break;
     689            default:
     690                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     691                        PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED,
     692                        item->pType);
     693                break;
     694            }
     695        } else if (item->type == PS_META_STR) {
     696            fits_update_key(fits->p_fd,
     697                            TSTRING,
     698                            item->name,
     699                            item->data.V,
     700                            item->comment,
     701                            &status);
     702        }
     703
     704        if ( status != 0) {
     705            char fitsErr[MAX_STRING_LENGTH];
     706            (void)fits_get_errstatus(status, fitsErr);
     707            psError(PS_ERR_IO, true,
     708                    PS_ERRORTEXT_psFits_WRITE_FAILED,
     709                    fits->filename, fitsErr);
     710            return false;
     711        }
     712    }
    585713
    586714    return true;
     
    589717psMetadata* psFitsReadTableRow(psFits* fits,
    590718                               int row)
    591 {}
     719{
     720    long numRows;
     721    int numCols;
     722    int status = 0;
     723
     724    if (fits == NULL) {
     725        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     726                PS_ERRORTEXT_psFits_NULL);
     727        return NULL;
     728    }
     729
     730    // check to see if we even are positioned on a table HDU
     731    int hdutype;
     732    fits_get_hdu_type(fits->p_fd,&hdutype, &status);
     733    if ( status != 0) {
     734        char fitsErr[MAX_STRING_LENGTH];
     735        (void)fits_get_errstatus(status, fitsErr);
     736        psError(PS_ERR_IO, true,
     737                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     738                fitsErr);
     739        return NULL;
     740    }
     741    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     742        psError(PS_ERR_IO, true,
     743                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     744        return NULL;
     745    }
     746
     747    // get the size of the FITS table
     748    fits_get_num_rows(fits->p_fd, &numRows, &status);
     749    fits_get_num_cols(fits->p_fd, &numCols, &status);
     750    if ( status != 0) {
     751        char fitsErr[MAX_STRING_LENGTH];
     752        (void)fits_get_errstatus(status, fitsErr);
     753        psError(PS_ERR_IO, true,
     754                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
     755                fitsErr);
     756        return NULL;
     757    }
     758
     759    // the row parameter in the proper range?
     760    if (row < 1 || row > numRows) {
     761        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     762                PS_ERRORTEXT_psFits_ROW_INVALID,
     763                row,numRows);
     764        return NULL;
     765    }
     766
     767    psMetadata* data = psMetadataAlloc();
     768
     769    int typecode;
     770    long repeat;
     771    long width;
     772    char name[60];
     773    for (int col = 1; col <= numCols; col++) {
     774        // get the column name
     775        if (hdutype == BINARY_TBL) {
     776            fits_get_bcolparms(fits->p_fd, col, name,
     777                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
     778        } else {
     779            fits_get_acolparms(fits->p_fd, col, name,
     780                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
     781        }
     782
     783        // get the column type
     784        fits_get_coltype(fits->p_fd, col, &typecode, &repeat, &width, &status);
     785
     786        if (status == 0) {
     787
     788            #define READ_TABLE_ROW_CASE(FITSTYPE, TYPE) \
     789        case FITSTYPE: { \
     790                ps##TYPE value; \
     791                int anynul = 0; \
     792                fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
     793                              1, 1, NULL, &value, &anynul, &status); \
     794                if (anynul == 0) { \
     795                    psMetadataAdd(data,PS_LIST_TAIL, name, \
     796                                  PS_TYPE_S32, PS_META_PRIMITIVE, \
     797                                  "", value); \
     798                } \
     799            } \
     800            break;
     801
     802            switch (typecode) {
     803            case TBYTE:
     804            case TSHORT:
     805                READ_TABLE_ROW_CASE(TLONG, S32)
     806                READ_TABLE_ROW_CASE(TFLOAT, F32)
     807                READ_TABLE_ROW_CASE(TDOUBLE, F64)
     808            default:
     809                psTrace("psFits.psFitsReadTableRow", 2,
     810                        "Column %d or row %d was of a non primitive type, %d",
     811                        col, row, typecode);
     812            }
     813        }
     814
     815        if ( status != 0) {
     816            char fitsErr[MAX_STRING_LENGTH];
     817            (void)fits_get_errstatus(status, fitsErr);
     818            psError(PS_ERR_IO, true,
     819                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
     820                    col,row,fitsErr);
     821            psFree(data);
     822            return NULL;
     823        }
     824
     825    }
     826
     827    return data;
     828}
    592829
    593830psArray* psFitsReadTableColumn(psFits* fits,
    594831                               const char* colname)
    595 {}
     832{
     833    int colnum = 0;
     834    int status = 0;
     835
     836    if (fits == NULL) {
     837        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     838                PS_ERRORTEXT_psFits_NULL);
     839        return NULL;
     840    }
     841
     842    // check to see if we even are positioned on a table HDU
     843    int hdutype;
     844    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     845        char fitsErr[MAX_STRING_LENGTH];
     846        (void)fits_get_errstatus(status, fitsErr);
     847        psError(PS_ERR_IO, true,
     848                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     849                fitsErr);
     850        return NULL;
     851    }
     852    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     853        psError(PS_ERR_IO, true,
     854                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     855        return NULL;
     856    }
     857
     858    // find the column by name
     859    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     860        char fitsErr[MAX_STRING_LENGTH];
     861        (void)fits_get_errstatus(status, fitsErr);
     862        psError(PS_ERR_IO, true,
     863                PS_ERRORTEXT_psFits_FIND_COLUMN,
     864                colname, fitsErr);
     865        return NULL;
     866    }
     867
     868    // get the number of rows
     869    long numRows = 0;
     870    fits_get_num_rows(fits->p_fd, &numRows, &status);
     871
     872    psArray* result = psArrayAlloc(numRows);
     873
     874    fits_read_col_str(fits->p_fd,
     875                      colnum,
     876                      1, // firstrow
     877                      1, // firestelem
     878                      numRows,
     879                      "", // nulstr
     880                      (char**)result->data,
     881                      NULL,
     882                      &status);
     883
     884    if ( status != 0) {
     885        char fitsErr[MAX_STRING_LENGTH];
     886        (void)fits_get_errstatus(status, fitsErr);
     887        psError(PS_ERR_IO, true,
     888                PS_ERRORTEXT_psFits_TABLE_READ_COL,
     889                fitsErr);
     890        return NULL;
     891    }
     892
     893    return result;
     894}
    596895
    597896psVector* psFitsReadTableColumnNum(psFits* fits,
    598897                                   const char* colname)
    599 {}
     898{
     899    int colnum = 0;
     900    int status = 0;
     901
     902    if (fits == NULL) {
     903        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     904                PS_ERRORTEXT_psFits_NULL);
     905        return NULL;
     906    }
     907
     908    // check to see if we even are positioned on a table HDU
     909    int hdutype;
     910    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     911        char fitsErr[MAX_STRING_LENGTH];
     912        (void)fits_get_errstatus(status, fitsErr);
     913        psError(PS_ERR_IO, true,
     914                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     915                fitsErr);
     916        return NULL;
     917    }
     918    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     919        psError(PS_ERR_IO, true,
     920                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     921        return NULL;
     922    }
     923
     924    // find the column by name
     925    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     926        char fitsErr[MAX_STRING_LENGTH];
     927        (void)fits_get_errstatus(status, fitsErr);
     928        psError(PS_ERR_IO, true,
     929                PS_ERRORTEXT_psFits_FIND_COLUMN,
     930                colname, fitsErr);
     931        return NULL;
     932    }
     933
     934    // get the number of rows
     935    long numRows = 0;
     936    fits_get_num_rows(fits->p_fd, &numRows, &status);
     937
     938    // get the column datatype.
     939    int typecode;
     940    long repeat;
     941    long width;
     942    if ( fits_get_eqcoltype(fits->p_fd, colnum, &typecode, &repeat, &width, &status) != 0) {
     943        char fitsErr[MAX_STRING_LENGTH];
     944        (void)fits_get_errstatus(status, fitsErr);
     945        psError(PS_ERR_IO, true,
     946                PS_ERRORTEXT_psFits_GET_COLTYPE,
     947                fitsErr);
     948        return NULL;
     949    }
     950
     951    psVector* result = psVectorAlloc(numRows, convertFitsToPsType(typecode));
     952
     953    fits_read_col(fits->p_fd, typecode, colnum, 1 /* firstrow */,
     954                  1 /* firstelem */, numRows, NULL, result->data.V,
     955                  NULL, &status);
     956
     957    if ( status != 0) {
     958        char fitsErr[MAX_STRING_LENGTH];
     959        (void)fits_get_errstatus(status, fitsErr);
     960        psError(PS_ERR_IO, true,
     961                PS_ERRORTEXT_psFits_TABLE_READ_COL,
     962                fitsErr);
     963        return NULL;
     964    }
     965
     966    return result;
     967}
    600968
    601969
    602970psArray* psFitsReadTable(psFits* fits)
    603 {}
     971{
     972    int status = 0;
     973
     974    if (fits == NULL) {
     975        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     976                PS_ERRORTEXT_psFits_NULL);
     977        return NULL;
     978    }
     979
     980    // check to see if we even are positioned on a table HDU
     981    int hdutype;
     982    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
     983        char fitsErr[MAX_STRING_LENGTH];
     984        (void)fits_get_errstatus(status, fitsErr);
     985        psError(PS_ERR_IO, true,
     986                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
     987                fitsErr);
     988        return NULL;
     989    }
     990    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     991        psError(PS_ERR_IO, true,
     992                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
     993        return NULL;
     994    }
     995
     996    // get the size of the FITS table
     997    long numRows = 0;
     998    int numCols = 0;
     999    fits_get_num_rows(fits->p_fd, &numRows, &status);
     1000    fits_get_num_cols(fits->p_fd, &numCols, &status);
     1001    if ( status != 0) {
     1002        char fitsErr[MAX_STRING_LENGTH];
     1003        (void)fits_get_errstatus(status, fitsErr);
     1004        psError(PS_ERR_IO, true,
     1005                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
     1006                fitsErr);
     1007        return NULL;
     1008    }
     1009
     1010    psArray* table = psArrayAlloc(numCols);
     1011
     1012    for (int row = 0; row < numRows; row++) {
     1013        table->data[row] = psFitsReadTableRow(fits,row);
     1014    }
     1015
     1016    return table;
     1017}
    6041018
    6051019bool psFitsWriteTable(psFits* fits,
    606                       psArray* table)
    607 {}
     1020                      psMetadata* header,
     1021                      psArray* table,
     1022                      char* extname)
     1023{
     1024    int status = 0;
     1025
     1026    if (fits == NULL) {
     1027        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     1028                PS_ERRORTEXT_psFits_NULL);
     1029        return NULL;
     1030    }
     1031
     1032    if (table == NULL) {
     1033        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     1034                PS_ERRORTEXT_psFits_IMAGE_NULL);
     1035        return false;
     1036    }
     1037
     1038    int rows = table->n;
     1039
     1040    // find all the columns needed
     1041    psArray* columns = psArrayAlloc(16);
     1042    columns->n=0;
     1043
     1044    // find the unique items in the array of metadata 'rows'
     1045    psMetadataItem* item;
     1046    for (int row=0; row < rows; row++) {
     1047        psMetadata* rowMeta = table->data[row];
     1048        if (rowMeta != NULL) {
     1049            psListIterator* iter = psListIteratorAlloc(rowMeta->list,
     1050                                   PS_LIST_HEAD);
     1051            while ( (item=psListGetNext(iter)) != NULL) {
     1052                if (item->type == PS_META_PRIMITIVE) {
     1053                    bool found = false;
     1054                    for (int n=0; n < columns->n && ! found; n++) {
     1055                        if (strcmp(item->name,
     1056                                   ((psMetadataItem*)(columns->data[n]))->name) == 0) {
     1057                            found = true;
     1058                        }
     1059                    }
     1060                    if (! found) {
     1061                        psArrayAdd(columns, columns->nalloc, item);
     1062                    }
     1063                }
     1064            }
     1065            psFree(iter);
     1066        }
     1067    }
     1068
     1069    if (columns->n == 0) { // no table columns found
     1070        // XXX: Error?
     1071        return false;
     1072    }
     1073
     1074    //create list of column names and types.
     1075    psArray* columnNames = psArrayAlloc(columns->n);
     1076    psArray* columnTypes = psArrayAlloc(columns->n);
     1077    for (int n=0; n < columns->n; n++) {
     1078        char* fitsType;
     1079        columnNames->data[n] = ((psMetadataItem*)columns->data[n])->name;
     1080        if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
     1081                                          &fitsType)) {
     1082            // XXX: error message
     1083            return false;
     1084        }
     1085        columnTypes->data[n] = fitsType;
     1086    }
     1087
     1088    fits_create_tbl(fits->p_fd,
     1089                    BINARY_TBL,
     1090                    table->n, // number of rows in table
     1091                    columns->n, // number of columns in table
     1092                    (char**)columnNames->data, // names of the columns
     1093                    (char**)columnTypes->data, // format of the columns
     1094                    NULL, // physical unit of columns
     1095                    extname, // extension name
     1096                    &status);
     1097
     1098    // fill in the table elements with data
     1099    for (int n = 0; n < columns->n; n++) {
     1100        int row;
     1101        item = columns->data[n];
     1102        psArray* columnItems = psArrayAlloc(table->n);
     1103        for (row = 0; row < table->n; row++) {
     1104            columnItems->data[row] = psMetadataLookup(table->data[row],item->name);
     1105        }
     1106
     1107        if (item->type == PS_META_PRIMITIVE) {
     1108            psVector* col = psVectorAlloc(table->n, item->pType);
     1109            switch (item->pType) {
     1110            case PS_TYPE_S32:
     1111                for (row = 0; row < table->n; row++) {
     1112                    col->data.S32[row] = item->data.S32;
     1113                }
     1114                fits_write_col_int(fits->p_fd,
     1115                                   n, // column number
     1116                                   1, // firstrow
     1117                                   1, // firstelem
     1118                                   table->n, // nelements
     1119                                   col->data.S32,
     1120                                   &status);
     1121                break;
     1122            case PS_TYPE_F32:
     1123                for (row = 0; row < table->n; row++) {
     1124                    col->data.F32[row] = item->data.F32;
     1125                }
     1126                fits_write_col_flt(fits->p_fd,
     1127                                   n, // column number
     1128                                   1, // firstrow
     1129                                   1, // firstelem
     1130                                   table->n, // nelements
     1131                                   col->data.F32,
     1132                                   &status);
     1133                break;
     1134            case PS_TYPE_S64:
     1135                for (row = 0; row < table->n; row++) {
     1136                    col->data.F64[row] = item->data.F64;
     1137                }
     1138                fits_write_col_dbl(fits->p_fd,
     1139                                   n, // column number
     1140                                   1, // firstrow
     1141                                   1, // firstelem
     1142                                   table->n, // nelements
     1143                                   col->data.F64,
     1144                                   &status);
     1145                break;
     1146            default:
     1147                // XXX: error message
     1148                psFree(col);
     1149                psFree(columnItems);
     1150                psFree(columnNames);
     1151                psFree(columnTypes);
     1152                psFree(columns);
     1153                return false;
     1154            }
     1155
     1156        } else if (item->type == PS_META_STR) {
     1157            psArray* col = psArrayAlloc(table->n);
     1158            for (row = 0; row < table->n; row++) {
     1159                col->data[row] = item->data.V;
     1160            }
     1161            fits_write_col_str(fits->p_fd,
     1162                               n, // column number
     1163                               1, // firstrow
     1164                               1, // firstelem
     1165                               table->n, // nelements
     1166                               (char**)col->data,
     1167                               &status);
     1168        }
     1169    }
     1170
     1171    return true;
     1172}
  • trunk/psLib/src/fits/psFits.h

    r2681 r2806  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-12-10 02:50:15 $
     9 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-23 19:13:53 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    143143 */
    144144bool psFitsWriteHeader(
    145     psMetadata* header,                ///< the psMetadata data in which to write
     145    const psMetadata* header,          ///< the psMetadata data in which to write
    146146    psFits* fits                       ///< the psFits object
    147147);
     
    162162 *  @return bool        TRUE is the write was successful, otherwise FALSE.
    163163 */
    164 bool psFitsWriteImageSection(
    165     psFits* fits,                      ///< the psFits object
     164bool psFitsWriteImage(
     165    psFits* fits,                      ///< the psFits object
     166    const psMetadata* header,
    166167    const psImage* input,              ///< the image to output
    167     psRegion region,                   ///< the part of the FITS image to overwrite
    168     int z                              ///< the z-plane of the FITS image data cube to use
     168    int depth                          ///< the number of z-planes of the FITS image data cube
    169169);
    170170
     
    223223bool psFitsWriteTable(
    224224    psFits* fits,                      ///< the psFits object
    225     psArray* table
     225    psMetadata* header,
     226    psArray* table,
    226227    ///< Array of psMetadata items, which contains the output data items of each row.
     228    char* extname
    227229);
    228230
Note: See TracChangeset for help on using the changeset viewer.