IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 7224


Ignore:
Timestamp:
May 25, 2006, 2:48:20 PM (20 years ago)
Author:
Paul Price
Message:

Fixing problem that prevented us from writing a PHU consisting of a header only --- need to call fits_create_img in psFitsWriteHeader if there are not currently any HDUs. This generates the primary HDU (without having to put in the required headers manually), and allows subsequent calls to psFitsWriteImage to generate a new HDU (without having to put in the required headers manually). Required keywords are written by cfitsio.

Location:
trunk/psLib/src/fits
Files:
2 edited

Legend:

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

    r7221 r7224  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2006-05-25 23:41:18 $
     9 *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2006-05-26 00:48:20 $
    1111 *
    1212 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    3333// List of FITS header keys that may be duplicated; NULL-terminated
    3434static char *duplicateFitsKeys[] = {"COMMENT", "HIERARCH", "HISTORY", "", NULL};
     35
     36// List of FITS header keys not to write (handled by cfitsio); NULL-terminated
     37// XXX: Need to add table-related keywords here.
     38static char *noWriteFitsKeys[] = {"SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "EXTNAME",
     39                                  "BSCALE", "BZERO", NULL};
    3540
    3641psMetadata* psFitsReadHeader(psMetadata* out,
     
    216221{
    217222
    218     if (fits == NULL) {
    219         psError(PS_ERR_BAD_PARAMETER_NULL, true,
    220                 PS_ERRORTEXT_psFits_NULL);
     223    if (!fits) {
     224        psError(PS_ERR_BAD_PARAMETER_NULL, true, PS_ERRORTEXT_psFits_NULL);
    221225        return false;
    222226    }
    223227
    224     if (output == NULL) {
    225         psError(PS_ERR_BAD_PARAMETER_NULL, true,
    226                 PS_ERRORTEXT_psFits_METADATA_NULL);
     228    if (!output) {
     229        psError(PS_ERR_BAD_PARAMETER_NULL, true, PS_ERRORTEXT_psFits_METADATA_NULL);
    227230        return false;
    228231    }
    229232
    230     int status = 0;
    231 
    232     // Add required header keywords
    233     int chdu = psFitsGetExtNum(fits);
    234     if (chdu == 0) {
    235         psMetadataAddBool(output, PS_LIST_HEAD, "SIMPLE", PS_META_NO_REPLACE, "Simple FITS file?", true);
    236     }
    237     psMetadataAddS32(output, PS_LIST_HEAD + 1, "BITPIX", PS_META_NO_REPLACE, "Bits per pixel (default)", 16);
    238     psMetadataAddS32(output, PS_LIST_HEAD + 2, "NAXIS", PS_META_NO_REPLACE, "Number of axes (default)", 0);
    239 
    240     //transverse the metadata list and add each key.
    241 
    242     psListIterator* iter = psListIteratorAlloc(output->list,PS_LIST_HEAD,true);
    243     psMetadataItem* item;
    244     while ( (item=psListGetAndIncrement(iter)) != NULL ) {
     233    int status = 0;                     // Status of cfitsio calls
     234
     235    // Check to see if there are any extant HDUs
     236    int hdus = psFitsGetSize(fits);     // Number of HDUs
     237    if (hdus == 0) {
     238        // Need to create a dummy image HDU for the primary HDU
     239        fits_create_img(fits->fd, 16, 0, NULL, &status);
     240        if (status) {
     241            char fitsErr[MAX_STRING_LENGTH];
     242            (void)fits_get_errstatus(status, fitsErr);
     243            psError(PS_ERR_IO, true, "Unable to create primary header.\n%s\n", fitsErr);
     244            return false;
     245        }
     246    }
     247
     248    // Traverse the metadata list and add each key.
     249    psListIterator* iter = psListIteratorAlloc(output->list, PS_LIST_HEAD, true); // Iterator
     250    psMetadataItem* item;               // Item from iteration
     251    while ((item = psListGetAndIncrement(iter))) {
     252        // Check to see if the item should be ignored
     253        // We ignore particular (required) keywords, because these are written by CFITSIO
     254        // Furthermore, users tend to supply FITS headers that are wrong (e.g., after binning down the
     255        // image, the NAXISn haven't been changed; or after converting to F32, the BITPIX hasn't been changed)
     256        // so we'll take care of that for them.
     257        bool writeKey = true;           // Should we write this keyword?
     258        for (int i = 0; noWriteFitsKeys[i] && writeKey; i++) {
     259            if (strcmp(item->name, noWriteFitsKeys[i]) == 0) {
     260                writeKey = false;
     261            }
     262        }
     263        if (!writeKey) {
     264            // Don't write it; skip to the next key
     265            continue;
     266        }
     267
    245268        switch (item->type) {
    246269        case PS_DATA_BOOL: {
    247270                int value = item->data.B;
    248                 fits_update_key(fits->fd,
    249                                 TLOGICAL,
    250                                 item->name,
    251                                 &value,
    252                                 item->comment,
    253                                 &status);
     271                fits_update_key(fits->fd, TLOGICAL, item->name, &value, item->comment, &status);
    254272                break;
    255273            }
    256274        case PS_DATA_S8:
    257             fits_update_key(fits->fd,
    258                             TBYTE,
    259                             item->name,
    260                             &item->data.S8,
    261                             item->comment,
    262                             &status);
     275            fits_update_key(fits->fd, TBYTE, item->name, &item->data.S8, item->comment, &status);
    263276            break;
    264277        case PS_DATA_S16:
    265             fits_update_key(fits->fd,
    266                             TSHORT,
    267                             item->name,
    268                             &item->data.S16,
    269                             item->comment,
    270                             &status);
     278            fits_update_key(fits->fd, TSHORT, item->name, &item->data.S16, item->comment, &status);
    271279            break;
    272280        case PS_DATA_S32:
    273             fits_update_key(fits->fd,
    274                             TINT,
    275                             item->name,
    276                             &item->data.S32,
    277                             item->comment,
    278                             &status);
     281            fits_update_key(fits->fd, TINT, item->name, &item->data.S32, item->comment, &status);
    279282            break;
    280283        case PS_DATA_U8: {
    281284                unsigned short int temp = item->data.U8;
    282                 fits_update_key(fits->fd,
    283                                 TUSHORT,
    284                                 item->name,
    285                                 &temp,
    286                                 item->comment,
    287                                 &status);
     285                fits_update_key(fits->fd, TUSHORT, item->name, &temp, item->comment, &status);
    288286            }
    289287            break;
    290288        case PS_DATA_U16:
    291             fits_update_key(fits->fd,
    292                             TUSHORT,
    293                             item->name,
    294                             &item->data.U16,
    295                             item->comment,
    296                             &status);
     289            fits_update_key(fits->fd, TUSHORT, item->name, &item->data.U16, item->comment, &status);
    297290            break;
    298291        case PS_DATA_U32:
    299             fits_update_key(fits->fd,
    300                             TUINT,
    301                             item->name,
    302                             &item->data.U32,
    303                             item->comment,
    304                             &status);
     292            fits_update_key(fits->fd, TUINT, item->name, &item->data.U32, item->comment, &status);
    305293            break;
    306294        case PS_DATA_F32:
    307             fits_update_key(fits->fd,
    308                             TFLOAT,
    309                             item->name,
    310                             &item->data.F32,
    311                             item->comment,
    312                             &status);
     295            fits_update_key(fits->fd, TFLOAT, item->name, &item->data.F32, item->comment, &status);
    313296            break;
    314297        case PS_DATA_F64:
    315             fits_update_key(fits->fd,
    316                             TDOUBLE,
    317                             item->name,
    318                             &item->data.F64,
    319                             item->comment,
    320                             &status);
     298            fits_update_key(fits->fd, TDOUBLE, item->name, &item->data.F64, item->comment, &status);
    321299            break;
    322300        case PS_DATA_STRING:
    323             fits_update_key(fits->fd,
    324                             TSTRING,
    325                             item->name,
    326                             item->data.V,
    327                             item->comment,
    328                             &status);
     301            fits_update_key(fits->fd, TSTRING, item->name, item->data.V, item->comment, &status);
    329302            break;
    330303        default:  // all other META types are ignored
     
    332305        }
    333306
    334         if ( status != 0) {
     307        if (status != 0) {
    335308            char fitsErr[MAX_STRING_LENGTH];
    336309            (void)fits_get_errstatus(status, fitsErr);
    337             psError(PS_ERR_IO, true,
    338                     PS_ERRORTEXT_psFits_WRITE_FAILED,
    339                     fitsErr);
     310            psError(PS_ERR_IO, true, PS_ERRORTEXT_psFits_WRITE_FAILED, fitsErr);
    340311            return false;
    341312        }
     
    349320bool psFitsHeaderValidate(psMetadata *header)
    350321{
    351     bool valid = true;
    352     int status;
    353 
    354322    if (header == NULL) {
    355         psError(PS_ERR_BAD_PARAMETER_NULL, true,
    356                 PS_ERRORTEXT_psFits_METADATA_NULL);
     323        psError(PS_ERR_BAD_PARAMETER_NULL, true, PS_ERRORTEXT_psFits_METADATA_NULL);
    357324        return false;
    358325    }
    359326
    360     //transverse the metadata list and inspect at each key
    361 
    362     psListIterator* iter = psListIteratorAlloc(header->list,PS_LIST_HEAD,true);
    363     psMetadataItem* item;
    364     while ( (item=psListGetAndIncrement(iter)) != NULL ) {
    365         psDataType type = item->type;
    366 
    367         if (type > PS_DATA_STRING) { // i.e., a non-primitive type
     327    // Traverse the metadata list and inspect at each key
     328    psListIterator* iter = psListIteratorAlloc(header->list, PS_LIST_HEAD, true); // Iterator
     329    psMetadataItem* item;               // Item from iteration
     330    bool valid = true;                  // Are all items valid?
     331    while ((item = psListGetAndIncrement(iter))) {
     332        if (item->type > PS_DATA_STRING) { // i.e., a non-primitive type
    368333            valid = false;
    369334        }
     
    376341
    377342        // now, let's see if CFITSIO thinks this is a good keyword...
    378         status = 0;
     343        int status = 0;                 // Status from cfitsio calls
    379344        if (fits_test_keyword(item->name,&status) != 0) {
    380345            valid = false;
    381346        }
    382347    }
    383 
    384348    psFree(iter);
    385349
  • trunk/psLib/src/fits/psFitsImage.c

    r7161 r7224  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2006-05-22 22:38:27 $
     9 *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2006-05-26 00:48:20 $
    1111 *
    1212 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    331331    }
    332332
    333     int chdu = psFitsGetExtNum(fits);
    334     int hdus = psFitsGetSize(fits);
     333    int chdu = psFitsGetExtNum(fits);   // Current HDU number
     334    int hdus = psFitsGetSize(fits);     // Number of HDUs in file
    335335    if (! after) {
    336336        if (chdu == 0) {
     
    346346        status = 0;
    347347        fits_create_img(fits->fd, bitPix, naxis, naxes, &status);
    348 
    349348    } else {
    350349        fits_insert_img(fits->fd, bitPix, naxis, naxes, &status);
     
    363362
    364363    if (header) {
    365         // Update header with BITPIX, NAXIS[12], BSCALE, BZERO so we don't clobber the basic header
    366         psMetadataAddS32(header, PS_LIST_TAIL, "BITPIX", PS_META_REPLACE, "Bits per pixel", bitPix);
    367         psMetadataAddS32(header, PS_LIST_TAIL, "NAXIS",  PS_META_REPLACE, "Number of dimensions", naxis);
    368         psMetadataAddS32(header, PS_LIST_TAIL, "NAXIS1", PS_META_REPLACE, "Number of columns", numCols);
    369         psMetadataAddS32(header, PS_LIST_TAIL, "NAXIS2", PS_META_REPLACE, "Number of rows", numRows);
    370         psMetadataAddF64(header, PS_LIST_TAIL, "BSCALE", PS_META_REPLACE, "Pixel value scale", 1.0);
    371         psMetadataAddF64(header, PS_LIST_TAIL, "BZERO",  PS_META_REPLACE, "Pixel value offset", bZero);
    372         if (extname && strlen(extname) > 0) {
    373             psMetadataAddStr(header, PS_LIST_TAIL, "EXTNAME", PS_META_REPLACE, "Extenion Name", extname);
    374         }
    375364        psFitsWriteHeader(header, fits);
    376     } else {
    377         // Write the necessary headers manually
    378         fits_write_key_dbl(fits->fd, "BZERO", bZero, 12, "Pixel Value Offset", &status);
    379         fits_write_key_dbl(fits->fd, "BSCALE", 1.0, 12, "Pixel Value Scale", &status);
    380         // Regrettably have to cast away "const" on extname, because CFITSIO is horrible
    381         fits_write_key_str(fits->fd, "EXTNAME", (char *)extname, "Extension name", &status);
    382     }
    383 
     365    }
    384366    if (input->parent == NULL) { // if no parent, assume that the image data is contiguous
    385367        fits_write_img(fits->fd,
     
    402384    }
    403385
    404     if ( status != 0) {
     386    if (status != 0) {
    405387        char fitsErr[MAX_STRING_LENGTH];
    406388        (void)fits_get_errstatus(status, fitsErr);
Note: See TracChangeset for help on using the changeset viewer.