IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:45:22 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/simmosaic_branches
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/simmosaic_branches

  • branches/simmosaic_branches/psLib/src/fits/psFitsHeader.c

    r23376 r27839  
    5050
    5151// List of the start of FITS header keys not to write (handled by cfitsio); NULL-terminated
    52 static const char *noWriteFitsKeyStarts[] = { "NAXIS", "TTYPE", "TFORM", NULL };
     52static const char *noWriteFitsKeyStarts[] = { "NAXIS", "TTYPE", "TFORM", "TZERO", "TSCAL", NULL };
    5353
    5454// List of compressed FITS header keys not to write (handled by cfitsio); NULL-terminated
     
    148148}
    149149
    150 
    151150bool psFitsCheckCompressedImagePHU(const psFits *fits, psMetadata *header)
    152151{
     
    306305                keyType = 'C';
    307306            }
     307            psTrace("psLib.fits", 3, "Reading keyword %s, type %c\n", keyName, keyType);
    308308            if (status != 0) {
    309309                break;
     
    328328                                               -INFINITY);
    329329                } else {
    330                     success = psMetadataAddS32(header, PS_LIST_TAIL, keyNameTrans, dupFlag, keyComment,
    331                                                atoi(keyValue));
     330                    long long value = atoll(keyValue); // Value
     331                    if (value > PS_MIN_S32 && value < PS_MAX_S32) {
     332                        success = psMetadataAddS32(header, PS_LIST_TAIL, keyNameTrans, dupFlag, keyComment,
     333                                                   value);
     334                    } else {
     335                        success = psMetadataAddS64(header, PS_LIST_TAIL, keyNameTrans, dupFlag, keyComment,
     336                                                   value);
     337                    }
    332338                }
    333339                break;
     
    497503static bool fitsWriteHeader(psFits *fits, // The FITS file handle
    498504                            const psMetadata *output, // Metadata that is to be output into the FITS file
    499                             bool keyStarts // Write out the key starts?
     505                            bool keyStarts, // Write out the key starts?
     506                            bool phuImage   // Are we writing a PHU image?
    500507                           )
    501508{
    502509    int status = 0;                     // Status of cfitsio calls
     510    int extnum = psFitsGetExtNum(fits); // Number of extension
    503511    bool simple = true;                 // If SIMPLE is T, then the file should conform to the FITS standard
    504512    psFitsCompressionType compress = psFitsCompressionGetType(fits); // Compression type
    505     if (psFitsGetExtNum(fits) == 0) {
     513    if (extnum == 0) {
     514
    506515        // We allow the user to write SIMPLE, but it must be boolean
    507516        psMetadataItem *simpleItem = psMetadataLookup(output, "SIMPLE"); // SIMPLE in the header
    508517        if (simpleItem) {
    509             if (simpleItem->type != PS_DATA_BOOL) {
    510                 psError(PS_ERR_BAD_PARAMETER_TYPE, true, "SIMPLE in a FITS header must be of boolean type: "
    511                         "not %x --- assuming FALSE.\n", simpleItem->type);
     518            if (simpleItem->type != PS_DATA_BOOL || !simpleItem->data.B) {
    512519                int value = false;          // Temporary holder for boolean
     520                psWarning("Writing SIMPLE=F to FITS header by request");
    513521                fits_update_key(fits->fd, TLOGICAL, "SIMPLE", &value,
    514522                                "File does not conform to FITS standard", &status);
    515523                simple = false;
    516             } else if (!simpleItem->data.B) {
    517                 simple = false;
    518                 int value = false;      // Temporary holder for boolean
    519                 fits_update_key(fits->fd, TLOGICAL, "SIMPLE", &value,
    520                                 "File does not conform to FITS standard", &status);
    521524            }
    522525            // Uncompressed SIMPLE = T is taken care of by cfitsio.
     
    526529    bool compressing = ((!fits->options || fits->options->conventions.compression) &&
    527530                        compress != PS_FITS_COMPRESS_NONE) ? true : false; // Are we compressing?
    528 
    529531    if (compressing) {
    530532        psMetadataItem *simpleItem = psMetadataLookup(output, "SIMPLE"); // SIMPLE in the header
     
    538540            }
    539541        }
    540         //        int value = simple;             // Temporary holder for boolean
    541         //        fits_update_key(fits->fd, TLOGICAL, "ZSIMPLE", &value,
    542         //                        "Uncompressed file's conformance to FITS standard", &status);
     542        if (simple && phuImage && extnum == 1) {
     543            // ZSIMPLE is required for decompression with funpack, etc.  For funpack to work, ZSIMPLE needs to
     544            // go early in the FITS header (otherwise we get "Extension doesn't start with SIMPLE or XTENSION
     545            // keyword.").  We put it after ZIMAGE by reading ZIMAGE (which sets the insertion pointer) and
     546            // then inserting ZSIMPLE.
     547            char comment[FLEN_CARD];    // Comment for ZIMAGE; unused
     548            int value;                  // Value for ZIMAGE; unused
     549            psTrace("psLib.fits", 3, "Writing header ZSIMPLE to preserve PHU");
     550            fits_read_key(fits->fd, TLOGICAL, "ZIMAGE", &value, comment, &status);
     551            fits_insert_key_log(fits->fd, "ZSIMPLE", simple, "Uncompressed file's conforms to FITS", &status);
     552        }
    543553    }
    544554
     
    560570            // to preserve NAXISn etc for reference, so we don't do this.
    561571
     572            if (keywordInList(name, noWriteFitsKeys) ||
     573                (keyStarts && keywordStartsWith(name, noWriteFitsKeyStarts))) {
     574                psTrace("psLib.fits", 3, "Not writing FITS keyword %s", name);
     575                continue;
     576            }
     577
    562578            // Options for compression
    563579            if (compressing) {
     
    567583                if (keywordInList(name, noWriteCompressedKeys) ||
    568584                    (keyStarts && keywordStartsWith(name, noWriteCompressedKeyStarts))) {
     585                    psTrace("psLib.fits", 3, "Not writing FITS keyword %s", name);
    569586                    continue;
    570587                }
    571588            } else if (keywordInList(name, noWriteCompressedKeys) ||
    572589                       (keyStarts && keywordStartsWith(name, noWriteCompressedKeyStarts))) {
    573                 continue;
    574             }
    575 
    576             if (keywordInList(name, noWriteFitsKeys) ||
    577                 (keyStarts && keywordStartsWith(name, noWriteFitsKeyStarts))) {
     590                psTrace("psLib.fits", 3, "Not writing FITS keyword %s", name);
    578591                continue;
    579592            }
     
    584597                psWarning("COMMENT header is not of type STRING (%x) --- ignored.", item->type);
    585598            } else {
     599                psTrace("psLib.fits", 5, "Writing header COMMENT: %s", item->data.str);
    586600                fits_write_comment(fits->fd, item->data.str, &status);
    587601            }
     
    590604                psWarning("COMMENT header is not of type STRING (%x) --- ignored.", item->type);
    591605            } else {
     606                psTrace("psLib.fits", 5, "Writing header HISTORY: %s", item->data.str);
    592607                fits_write_history(fits->fd, item->data.str, &status);
    593608            }
     
    597612              case PS_DATA_BOOL: {
    598613                  int value = item->data.B;
     614                  psTrace("psLib.fits", 5, "Writing BOOL header %s: %d", name, value);
    599615                  fits_update_key(fits->fd, TLOGICAL, name, &value, item->comment, &status);
    600616                  break;
    601617              }
    602618              case PS_DATA_S8:
     619                psTrace("psLib.fits", 5, "Writing S8 header %s: %d", name, (int)item->data.S8);
    603620                fits_update_key(fits->fd, TBYTE, name, &item->data.S8, item->comment, &status);
    604621                break;
    605622              case PS_DATA_S16:
     623                psTrace("psLib.fits", 5, "Writing S16 header %s: %d", name, (int)item->data.S16);
    606624                fits_update_key(fits->fd, TSHORT, name, &item->data.S16, item->comment, &status);
    607625                break;
    608626              case PS_DATA_S32:
     627                psTrace("psLib.fits", 5, "Writing S32 header %s: %d", name, (int)item->data.S32);
    609628                fits_update_key(fits->fd, TINT, name, &item->data.S32, item->comment, &status);
    610629                break;
    611630              case PS_DATA_S64:
     631                psTrace("psLib.fits", 5, "Writing S64 header %s: %" PRId64, name, item->data.S64);
    612632                fits_update_key(fits->fd, TLONGLONG, name, &item->data.S64, item->comment, &status);
    613633                break;
    614634              case PS_DATA_U8: {
    615635                  unsigned short int temp = item->data.U8;
     636                psTrace("psLib.fits", 5, "Writing U8 header %s: %d", name, (int)item->data.U8);
    616637                  fits_update_key(fits->fd, TUSHORT, name, &temp, item->comment, &status);
    617638                  break;
    618639              }
    619640              case PS_DATA_U16:
     641                psTrace("psLib.fits", 5, "Writing U16 header %s: %d", name, (int)item->data.U16);
    620642                fits_update_key(fits->fd, TUSHORT, name, &item->data.U16, item->comment, &status);
    621643                break;
    622644              case PS_DATA_U32:
     645                psTrace("psLib.fits", 5, "Writing U32 header %s: %d", name, (unsigned int)item->data.U32);
    623646                fits_update_key(fits->fd, TUINT, name, &item->data.U32, item->comment, &status);
    624647                break;
     
    631654                }
    632655                psS64 temp = item->data.U64; // Signed version
     656                psTrace("psLib.fits", 5, "Writing U64 header %s: %" PRIu64, name, item->data.U64);
    633657                fits_update_key(fits->fd, TLONGLONG, name, &temp, item->comment, &status);
    634658                break;
    635659              case PS_DATA_F32: {
    636660                  int infCheck = 0;         // Result of isinf()
     661                  psTrace("psLib.fits", 5, "Writing F32 header %s: %f", name, item->data.F32);
    637662                  if (isnan(item->data.F32)) {
    638663                      fits_update_key(fits->fd, TSTRING, name, "NaN", item->comment, &status);
     
    651676              case PS_DATA_F64: {
    652677                  int infCheck = 0;         // Result of isinf()
     678                  psTrace("psLib.fits", 5, "Writing F32 header %s: %lf", name, item->data.F64);
    653679                  if (isnan(item->data.F64)) {
    654680                      fits_update_key(fits->fd, TSTRING, name, "NaN", item->comment, &status);
     
    666692              }
    667693              case PS_DATA_STRING:
     694                psTrace("psLib.fits", 5, "Writing STR header %s: %s", name, item->data.str);
    668695                fits_update_key(fits->fd, TSTRING, name, item->data.V, item->comment, &status);
    669696                break;
     
    699726    PS_ASSERT_METADATA_NON_NULL(output, false);
    700727
    701     return fitsWriteHeader(fits, output, true);
     728    return fitsWriteHeader(fits, output, true, false);
     729}
     730
     731bool psFitsWriteHeaderImage(psFits *fits,
     732                            const psMetadata *output,
     733                            bool phuImage
     734                            )
     735{
     736    PS_ASSERT_FITS_NON_NULL(fits, false);
     737    PS_ASSERT_FITS_WRITABLE(fits, false);
     738    PS_ASSERT_METADATA_NON_NULL(output, false);
     739
     740    return fitsWriteHeader(fits, output, true, phuImage);
    702741}
    703742
     
    733772    }
    734773
    735     if (output && !fitsWriteHeader(fits, output, false)) {
     774    if (output && !fitsWriteHeader(fits, output, false, false)) {
    736775        psError(PS_ERR_IO, false, "Unable to write FITS header.\n");
    737776        return false;
Note: See TracChangeset for help on using the changeset viewer.