IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 20, 2007, 9:14:22 AM (18 years ago)
Author:
Paul Price
Message:

Adding check to see if we're on the PHU, in which case we
automatically move to the first extension (it's a common gotcha, so
let's make it easy for the user). In the process, refactoring code
to reduce duplication.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/fits/psFitsTable.c

    r15248 r15662  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2007-10-09 02:56:23 $
     9 *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2007-11-20 19:14:22 $
    1111 *
    1212 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    4242    if (fits_get_num_rows(fits->fd, &numRows, &status)) {
    4343        psFitsError(status, true, "Unable to determine number of rows in table.");
    44         return 0;
     44        return -1;
    4545    }
    4646
    4747    return numRows;
    4848}
     49
     50// Check the FITS file in preparation for reading a table
     51static bool readTableCheck(const psFits *fits // FITS file
     52                           )
     53{
     54    PS_ASSERT_FITS_NON_NULL(fits, NULL);
     55
     56    if (psFitsGetExtNum(fits) == 0 && !psFitsMoveExtNum(fits, 1, false)) {
     57        psError(PS_ERR_IO, false, "Unable to move to first extension to read table.");
     58        return false;
     59    }
     60
     61
     62    // check that we are positioned on a table HDU
     63    int status = 0;                     // CFITSIO status
     64    int hdutype;                        // Type of HDU
     65    fits_get_hdu_type(fits->fd, &hdutype, &status);
     66    if (psFitsError(status, true, "Could not determine the HDU type.")) {
     67        return false;
     68    }
     69    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
     70        psError(PS_ERR_IO, true, _("Current FITS HDU is not a table."));
     71        return false;
     72    }
     73    return true;
     74}
     75
    4976
    5077psMetadata* psFitsReadTableRow(const psFits* fits,
     
    5481    PS_ASSERT_INT_NONNEGATIVE(row, NULL);
    5582
     83    if (!readTableCheck(fits)) {
     84        return NULL;
     85    }
     86
     87    // get the size of the FITS table
    5688    long numRows;
    5789    int numCols;
    5890    int status = 0;
    59 
    60     // check to see if we even are positioned on a table HDU
    61     int hdutype;
    62     fits_get_hdu_type(fits->fd,&hdutype, &status);
    63     if ( status != 0) {
    64         char fitsErr[MAX_STRING_LENGTH];
    65         (void)fits_get_errstatus(status, fitsErr);
    66         psError(PS_ERR_IO, true,
    67                 _("Could not determine the HDU type. CFITSIO Error: %s"),
    68                 fitsErr);
    69         return NULL;
    70     }
    71     if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
    72         psError(PS_ERR_IO, true,
    73                 _("Current FITS HDU type must be a table."));
    74         return NULL;
    75     }
    76 
    77     // get the size of the FITS table
    7891    fits_get_num_rows(fits->fd, &numRows, &status);
    7992    fits_get_num_cols(fits->fd, &numCols, &status);
    80     if ( status != 0) {
    81         char fitsErr[MAX_STRING_LENGTH];
    82         (void)fits_get_errstatus(status, fitsErr);
    83         psError(PS_ERR_IO, true,
    84                 _("Failed to determine the size of the current HDU table. CFITSIO Error: %s"),
    85                 fitsErr);
     93    if (status != 0) {
     94        psFitsError(status, true, "Failed to determine the size of the current HDU table.");
    8695        return NULL;
    8796    }
     
    97106
    98107    psMetadata* data = psMetadataAlloc();
     108
     109    int hdutype;                        // Type of HDU: need to distinguish ASCII and binary tables
     110    fits_get_hdu_type(fits->fd, &hdutype, &status);
     111    if (psFitsError(status, true, "Could not determine the HDU type.")) {
     112        return false;
     113    }
    99114
    100115    int typecode;
     
    113128        // get the column type
    114129        fits_get_coltype(fits->fd, col, &typecode, &repeat, &width, &status);
    115 
    116         if (status == 0) {
    117 
    118             #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE, VECTYPE) \
     130        if (psFitsError(status, true, "Unable to get column type for column %d", col)) {
     131            psFree(data);
     132            return NULL;
     133        }
     134
     135#define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE, VECTYPE) \
    119136        case FITSTYPE: { \
    120137                if (repeat == 1) { \
     
    144161            }
    145162
    146             switch (typecode) {
    147             case TBYTE:
    148             case TSHORT:
    149             case TLONGLONG:
    150                 READ_TABLE_ROW_CASE(TLONG, long, S32,S32)
    151                 READ_TABLE_ROW_CASE(TFLOAT, float, F32,F32)
    152                 READ_TABLE_ROW_CASE(TDOUBLE, double, F64,F64)
    153                 READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL,S8);
    154             case TSTRING: {
    155                     char* value = psAlloc(repeat+1);
    156                     int anynul = 0;
    157                     fits_read_col(fits->fd, TSTRING, col,row+1,
    158                                   1, 1, NULL, &value, &anynul, &status);
    159                     psTrace("psLib.fits",5,"Column #%i, '%s', is type %i, repeat %li, value = %s\n",
    160                             col, name, typecode, repeat, value);
    161                     if (anynul == 0) {
    162                         psMetadataAdd(data,PS_LIST_TAIL, name,
    163                                       PS_DATA_STRING,
    164                                       "", value);
    165                     }
    166                     psFree(value);
    167                     break;
    168                 }
    169             default:
    170                 psWarning("Data type (%d) not supportted for column %d",
    171                           typecode, col);
    172 
    173                 psTrace("psLib.fits", 2,
    174                         "Column %d or row %d was of a non primitive type, %d",
    175                         col, row, typecode);
    176             }
    177         }
    178 
    179         if ( status != 0) {
    180             char fitsErr[MAX_STRING_LENGTH];
    181             (void)fits_get_errstatus(status, fitsErr);
    182             psError(PS_ERR_IO, true,
    183                     _("Failed to retrieve table element (%d,%d). CFITSIO Error: %s"),
    184                     col,row,fitsErr);
     163        switch (typecode) {
     164          case TBYTE:
     165          case TSHORT:
     166          case TLONGLONG:
     167            READ_TABLE_ROW_CASE(TLONG, long, S32, S32);
     168            READ_TABLE_ROW_CASE(TFLOAT, float, F32, F32);
     169            READ_TABLE_ROW_CASE(TDOUBLE, double, F64, F64);
     170            READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL, S8);
     171          case TSTRING: {
     172              psString value = psStringAlloc(repeat);
     173              int anynul = 0;
     174              fits_read_col(fits->fd, TSTRING, col,row+1, 1, 1, NULL, &value, &anynul, &status);
     175              psTrace("psLib.fits", 5, "Column #%i, '%s', is type %i, repeat %li, value = %s\n",
     176                      col, name, typecode, repeat, value);
     177              if (anynul == 0) {
     178                  psMetadataAdd(data,PS_LIST_TAIL, name, PS_DATA_STRING, NULL, value);
     179              }
     180              psFree(value);
     181              break;
     182          }
     183          default:
     184            psWarning("Data type (%d) not supportted for column %d", typecode, col);
     185            psTrace("psLib.fits", 2, "Column %d or row %d was of a non primitive type, %d",
     186                    col, row, typecode);
     187        }
     188
     189        if (psFitsError(status, true, "Failed to retrieve table element (%d,%d)", col, row)) {
    185190            psFree(data);
    186191            return NULL;
    187192        }
    188 
    189193    }
    190194
     
    198202    PS_ASSERT_STRING_NON_EMPTY(colname, NULL);
    199203
     204    if (!readTableCheck(fits)) {
     205        return NULL;
     206    }
     207
    200208    int colnum = 0;
    201209    int status = 0;
    202210
    203     // check to see if we even are positioned on a table HDU
    204     int hdutype;
    205     if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
    206         char fitsErr[MAX_STRING_LENGTH];
    207         (void)fits_get_errstatus(status, fitsErr);
    208         psError(PS_ERR_IO, true,
    209                 _("Could not determine the HDU type. CFITSIO Error: %s"),
    210                 fitsErr);
    211         return NULL;
    212     }
    213     if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
    214         psError(PS_ERR_IO, true,
    215                 _("Current FITS HDU type must be a table."));
    216         return NULL;
    217     }
    218 
    219211    // find the column by name
    220     if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
    221         char fitsErr[MAX_STRING_LENGTH];
    222         (void)fits_get_errstatus(status, fitsErr);
    223         psError(PS_ERR_IO, true,
    224                 _("Specified column, %s, was not found. CFITSIO Error: %s"),
    225                 colname, fitsErr);
     212    if (fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     213        psFitsError(status, true, "Specified column, %s, was not found.", colname);
    226214        return NULL;
    227215    }
    228216
    229217    // get the number of rows
    230     long numRows = 0;
    231     fits_get_num_rows(fits->fd, &numRows, &status);
     218    long numRows = psFitsTableSize(fits);
     219    if (numRows == -1) {
     220        return NULL;
     221    }
    232222
    233223    // get the column length.
    234224    int width;
    235     if ( fits_get_col_display_width(fits->fd, colnum, &width, &status) != 0) {
    236         char fitsErr[MAX_STRING_LENGTH];
    237         (void)fits_get_errstatus(status, fitsErr);
    238         psError(PS_ERR_IO, true,
    239                 _("Could not determine the datatype of the table column. CFITSIO Error: %s"),
    240                 fitsErr);
     225    if (fits_get_col_display_width(fits->fd, colnum, &width, &status) != 0) {
     226        psFitsError(status, true, "Could not determine the datatype of the table column.");
    241227        return NULL;
    242228    }
     
    245231    psArray* result = psArrayAlloc(numRows);
    246232    for (int row = 0; row < numRows; row++) {
    247         result->data[row] = psAlloc((width+1)*sizeof(char));
    248     }
    249 
    250     fits_read_col_str(fits->fd,
    251                       colnum,
    252                       1, // firstrow
    253                       1, // firestelem
    254                       numRows,
    255                       "", // nulstr
    256                       (char**)result->data,
    257                       NULL,
    258                       &status);
    259 
    260     if ( status != 0) {
    261         char fitsErr[MAX_STRING_LENGTH];
    262         (void)fits_get_errstatus(status, fitsErr);
    263         psError(PS_ERR_IO, true,
    264                 _("Failed to read table column. CFITSIO Error: %s"),
    265                 fitsErr);
     233        result->data[row] = psStringAlloc(width);
     234    }
     235
     236    fits_read_col_str(fits->fd, colnum, 1, 1, numRows, "", (char**)result->data, NULL, &status);
     237    if (psFitsError(status, true, "Failed to read table column.")) {
     238        psFree(result);
    266239        return NULL;
    267240    }
     
    276249    PS_ASSERT_STRING_NON_EMPTY(colname, NULL);
    277250
     251    if (!readTableCheck(fits)) {
     252        return NULL;
     253    }
     254
    278255    int status = 0;
    279256    int colnum = 0;
    280257
    281     // check to see if we even are positioned on a table HDU
    282     int hdutype;
    283     if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
    284         char fitsErr[MAX_STRING_LENGTH];
    285         (void)fits_get_errstatus(status, fitsErr);
    286         psError(PS_ERR_IO, true,
    287                 _("Could not determine the HDU type. CFITSIO Error: %s"),
    288                 fitsErr);
    289         return NULL;
    290     }
    291     if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
    292         psError(PS_ERR_IO, true,
    293                 _("Current FITS HDU type must be a table."));
    294         return NULL;
    295     }
    296 
    297258    // find the column by name
    298     if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
    299         char fitsErr[MAX_STRING_LENGTH];
    300         (void)fits_get_errstatus(status, fitsErr);
    301         psError(PS_ERR_IO, true,
    302                 _("Specified column, %s, was not found. CFITSIO Error: %s"),
    303                 colname, fitsErr);
     259    if (fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
     260        psFitsError(status, true, "Specified column, %s, was not found.", colname);
    304261        return NULL;
    305262    }
    306263
    307264    // get the number of rows
    308     long numRows = 0;
    309     fits_get_num_rows(fits->fd,
    310                       &numRows,
    311                       &status);
     265    long numRows = psFitsTableSize(fits);
     266    if (numRows == -1) {
     267        return NULL;
     268    }
    312269
    313270    // get the column datatype.
     
    315272    long repeat;
    316273    long width;
    317     if ( fits_get_eqcoltype(fits->fd, colnum, &typecode, &repeat, &width, &status) != 0) {
    318         char fitsErr[MAX_STRING_LENGTH];
    319         (void)fits_get_errstatus(status, fitsErr);
    320         psError(PS_ERR_IO, true,
    321                 _("Could not determine the datatype of the table column. CFITSIO Error: %s"),
    322                 fitsErr);
     274    if (fits_get_eqcoltype(fits->fd, colnum, &typecode, &repeat, &width, &status) != 0) {
     275        psFitsError(status, true, "Could not determine the datatype of the table column.");
    323276        return NULL;
    324277    }
     
    326279    psVector* result = psVectorAlloc(numRows, p_psFitsTypeFromCfitsio(typecode));
    327280
    328     fits_read_col(fits->fd,
    329                   typecode,
    330                   colnum,
    331                   1 /* firstrow */,
    332                   1 /* firstelem */,
    333                   numRows,
    334                   NULL,
    335                   (psPtr)(result->data.U8),
    336                   NULL,
    337                   &status);
    338 
    339     if ( status != 0) {
    340         char fitsErr[MAX_STRING_LENGTH];
    341         (void)fits_get_errstatus(status, fitsErr);
    342         psError(PS_ERR_IO, true,
    343                 _("Failed to read table column. CFITSIO Error: %s"),
    344                 fitsErr);
     281    fits_read_col(fits->fd, typecode, colnum, 1, 1, numRows, NULL, (psPtr)(result->data.U8), NULL, &status);
     282    if (psFitsError(status, true, "Failed to read table column.")) {
     283        psFree(result);
    345284        return NULL;
    346285    }
     
    354293    PS_ASSERT_FITS_NON_NULL(fits, NULL);
    355294
    356     int status = 0;
    357 
    358     // check to see if we even are positioned on a table HDU
    359     int hdutype;
    360     if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
    361         char fitsErr[MAX_STRING_LENGTH];
    362         (void)fits_get_errstatus(status, fitsErr);
    363         psError(PS_ERR_IO, true,
    364                 _("Could not determine the HDU type. CFITSIO Error: %s"),
    365                 fitsErr);
    366         return NULL;
    367     }
    368     if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
    369         psError(PS_ERR_IO, true,
    370                 _("Current FITS HDU type must be a table."));
    371         return NULL;
    372     }
    373 
    374     // get the size of the FITS table
    375     long numRows = 0;
    376     fits_get_num_rows(fits->fd, &numRows, &status);
    377     if ( status != 0) {
    378         char fitsErr[MAX_STRING_LENGTH];
    379         (void)fits_get_errstatus(status, fitsErr);
    380         psError(PS_ERR_IO, true,
    381                 _("Failed to determine the size of the current HDU table. CFITSIO Error: %s"),
    382                 fitsErr);
    383         return NULL;
    384     }
    385 
     295    if (!readTableCheck(fits)) {
     296        return NULL;
     297    }
     298
     299    // get the number of rows
     300    long numRows = psFitsTableSize(fits);
     301    if (numRows == -1) {
     302        return NULL;
     303    }
    386304
    387305    psArray* table = psArrayAlloc(numRows);
    388306
    389307    for (int row = 0; row < numRows; row++) {
    390         psTrace("psLib.fits",5,"Reading row %i of %li\n",row, numRows);
     308        psTrace("psLib.fits",5,"Reading row %i of %li\n", row, numRows);
    391309        table->data[row] = psFitsReadTableRow(fits,row);
    392310    }
     
    536454                }
    537455                if (colItem->type != spec->type) {
    538                     psLogMsg(__func__, PS_LOG_WARN, "Differing type found for column %s: %x vs %x --- "
    539                              "using the first found.\n", colSpecItem->name, colItem->type, spec->type);
     456                    psWarning("Differing type found for column %s: %x vs %x --- using the first found.\n",
     457                              colSpecItem->name, colItem->type, spec->type);
    540458                }
    541459                if (colItem->type == PS_DATA_VECTOR) {
    542460                    psVector *vector = colItem->data.V; // The vector
    543461                    if (vector->type.type != spec->vectorType) {
    544                         psLogMsg(__func__, PS_LOG_WARN, "Differing vector type found for column %s: %x vs %x"
     462                        psWarning("Differing vector type found for column %s: %x vs %x "
    545463                                 "--- using the first found.\n", colSpecItem->name, vector->type.type,
    546464                                 spec->vectorType);
     
    616534
    617535    if (status != 0) {
    618         char fitsErr[MAX_STRING_LENGTH];
    619         fits_get_errstatus(status, fitsErr);
    620         psError(PS_ERR_LOCATION_INVALID, true,
    621                 "Unable to create FITS table with %ld columns and %ld rows: %s",
    622                 numColumns, table->n, fitsErr);
     536        psFitsError(status, true, "Unable to create FITS table with %ld columns and %ld rows",
     537                    numColumns, table->n);
    623538        psFree(colSpecsIter);
    624539        psFree(colSpecs);
     
    713628        // Check error status from writing column
    714629        if (status != 0) {
    715             char fitsErr[MAX_STRING_LENGTH];
    716             fits_get_errstatus(status, fitsErr);
    717             psError(PS_ERR_LOCATION_INVALID, true, "Unable to write column %ld of FITS table: %s",
    718                     colNum, fitsErr);
     630            psFitsError(status, true, "Unable to write column %ld of FITS table", colNum);
    719631            psFree(colSpecsIter);
    720632            psFree(colSpecs);
     
    738650    PS_ASSERT_INT_NONNEGATIVE(row, false);
    739651
     652    if (!readTableCheck(fits)) {
     653        return NULL;
     654    }
     655
    740656    int status = 0;
    741 
    742     // check to see if we even are positioned on a table HDU
    743     int hdutype;
    744     if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
    745         char fitsErr[MAX_STRING_LENGTH];
    746         (void)fits_get_errstatus(status, fitsErr);
    747         psError(PS_ERR_IO, true,
    748                 _("Could not determine the HDU type. CFITSIO Error: %s"),
    749                 fitsErr);
    750         return false;
    751     }
    752     if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
    753         psError(PS_ERR_IO, true,
    754                 _("Current FITS HDU type must be a table."));
    755         return false;
    756     }
    757 
    758     psMetadataIterator* iter = psMetadataIteratorAlloc((psPtr)data,PS_LIST_HEAD,NULL);
    759 
     657    psMetadataIterator* iter = psMetadataIteratorAlloc((psPtr)data, PS_LIST_HEAD, NULL);
    760658    psMetadataItem* item;
    761 
    762659    while ( (item=psMetadataGetAndIncrement(iter)) != NULL) {
    763660        if (PS_DATA_IS_PRIMITIVE(item->type) ||
     
    767664            int colnum = 0;
    768665
    769             if ( fits_get_colnum(fits->fd, CASESEN, item->name, &colnum, &status) == 0) {
     666            if (fits_get_colnum(fits->fd, CASESEN, item->name, &colnum, &status) == 0) {
    770667                // cooresponding column found in table
    771668                int dataType;
    772669                p_psFitsTypeToCfitsio(item->type, NULL, NULL, &dataType);
    773670
    774                 if (fits_write_col(fits->fd, dataType, colnum, row+1, 1, 1, &item->data,&status) != 0) {
    775                     char fitsErr[MAX_STRING_LENGTH];
    776                     (void)fits_get_errstatus(status, fitsErr);
    777                     psError(PS_ERR_IO, true,
    778                             _("Could not write data to file. CFITSIO Error: %s"),
    779                             fitsErr);
     671                if (fits_write_col(fits->fd, dataType, colnum, row+1, 1, 1, &item->data, &status) != 0) {
     672                    psFitsError(status, true, "Could not write data to file.");
    780673                    psFree(iter);
    781674                    return false;
     
    783676            } else {
    784677                // the column was not found.
    785                 psWarning("No column with the name '%s' exists in the table.",
    786                           item->name);
     678                psWarning("No column with the name '%s' exists in the table.", item->name);
    787679            }
    788680        }
Note: See TracChangeset for help on using the changeset viewer.