IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 19383


Ignore:
Timestamp:
Sep 4, 2008, 9:51:09 PM (18 years ago)
Author:
Paul Price
Message:

Adding capability for a mask to be provided when determining BSCALE,BZERO. This is required for the case when a large masked region of the image has been set to a constant (or close to a constant). If the mask is not provided in this case, then the standard deviation is under-estimated, leading to a choice of BSCALE,BZERO that adversely affects the dynamic range of the image. Added functions psFitsWriteImageWithMask, psFitsUpdateImageWithMask and psFitsInsertImageWithMask, and kept the APIs of psFitsWriteImage, psFitsUpdateImage and psFitsInsertImage so that this change shouldn't break anything.

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

Legend:

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

    r19270 r19383  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2008-08-29 01:01:39 $
     9 *  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2008-09-05 07:51:09 $
    1111 *
    1212 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    2828#include "psLogMsg.h"
    2929#include "psTrace.h"
    30 #include "psVector.h"
    3130#include "psRandom.h"
     31#include "psImage.h"
    3232#include "psImageStructManip.h"
    3333
     
    249249                                          psFitsFloat *floatType, // Type of custom floating-point
    250250                                          psFits *fits, // FITS file pointer
    251                                           const psImage *image, // Current type
     251                                          const psImage *image, // Image to convert
     252                                          const psImage *mask, // Mask image, or NULL
     253                                          psMaskType maskVal, // Value to mask
    252254                                          psRandom *rng, // Random number generator
    253255                                          bool newScaleZero // Determine a new BSCALE and BZERO?
     
    285287        if (newScaleZero) {
    286288            // Choose an appropriate BSCALE and BZERO
    287             if (!psFitsScaleDetermine(bscale, bzero, blank, image, fits)) {
     289            if (!psFitsScaleDetermine(bscale, bzero, blank, image, mask, maskVal, fits)) {
    288290                // We can't have the write dying for this reason --- try to save it somehow!
    289291                psWarning("Unable to determine BSCALE and BZERO for image --- refusing to quantise.");
     
    404406}
    405407
    406 psImage* psFitsReadImage(const psFits *fits, // the psFits object
     408psImage *psFitsReadImage(const psFits *fits, // the psFits object
    407409                         psRegion region, // the region in the FITS image to read
    408410                         int z          // the z-plane in the FITS image cube to read
     
    445447}
    446448
    447 psImage* psFitsReadImageBuffer(psImage *outImage, // Output image buffer
     449psImage *psFitsReadImageBuffer(psImage *outImage, // Output image buffer
    448450                               const psFits *fits, // the psFits object
    449451                               psRegion region, // the region in the FITS image to read
     
    497499}
    498500
    499 bool psFitsWriteImage(psFits* fits,
    500                       psMetadata* header,
    501                       const psImage* input,
    502                       int numZPlanes,
    503                       const char* extname)
     501bool psFitsWriteImage(psFits *fits, psMetadata *header, const psImage *input,
     502                      int numZPlanes, const char *extname)
     503{
     504    return psFitsWriteImageWithMask(fits, header, input, NULL, 0, numZPlanes, extname);
     505}
     506
     507bool psFitsWriteImageWithMask(psFits *fits, psMetadata *header, const psImage *input,
     508                              const psImage *mask, psMaskType maskVal, int numZPlanes,
     509                              const char *extname)
    504510{
    505511    PS_ASSERT_FITS_NON_NULL(fits, false);
     
    509515
    510516    psFitsMoveLast(fits);
    511     return psFitsInsertImage(fits,header,input,numZPlanes,extname,true);
    512 }
    513 
    514 bool psFitsInsertImage(psFits* fits, psMetadata* header, const psImage* image, int numZPlanes,
    515                        const char* extname, bool after)
     517    return psFitsInsertImageWithMask(fits, header, input, mask, maskVal, numZPlanes, extname, true);
     518}
     519
     520bool psFitsInsertImage(psFits *fits, psMetadata *header, const psImage *image, int numZPlanes,
     521                       const char *extname, bool after)
     522{
     523    return psFitsInsertImageWithMask(fits, header, image, NULL, 0, numZPlanes, extname, after);
     524}
     525
     526bool psFitsInsertImageWithMask(psFits *fits, psMetadata *header, const psImage *image,
     527                               const psImage *mask, psMaskType maskVal, int numZPlanes,
     528                               const char *extname, bool after)
    516529{
    517530    PS_ASSERT_FITS_NON_NULL(fits, false);
    518531    PS_ASSERT_FITS_WRITABLE(fits, false);
    519532    PS_ASSERT_IMAGE_NON_NULL(image, false);
     533    if (mask) {
     534        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, false);
     535        PS_ASSERT_IMAGES_SIZE_EQUAL(mask, image, false);
     536    }
    520537
    521538    int numCols = image->numCols;       // Number of columns for image
     
    529546    psFitsFloat floatType;              // Custom floating-point convention type
    530547    psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &blank, &floatType, fits, image,
    531                                                    NULL, true); // Image to write out
     548                                                   mask, maskVal, NULL, true); // Image to write out
    532549    if (!diskImage) {
    533550        psError(PS_ERR_UNKNOWN, false, "Unable to convert image to desired disk format.");
     
    557574    }
    558575    if (cfitsioBzero != 0.0) {
    559         // p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!
    560         psAssert(bzero == 0.0 && bscale == 1.0, "impossible");
     576        psAssert(bzero == 0.0 && bscale == 1.0,
     577                 "p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!");
    561578        bscale = 1.0;
    562579        bzero = cfitsioBzero;
     
    564581
    565582    psFitsOptions *options = fits->options; // FITS I/O options
    566     psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0, "impossible");
     583    psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0,
     584             "Something's not consistent");
    567585
    568586    int naxis = 3;                      // Number of axes
     
    630648        // own quantisation, the correct keyword is always "BLANK" instead of "ZBLANK".
    631649        fits_write_key_lng(fits->fd, "BLANK", blank, "Value for undefined pixels", &status);
     650        // But it seems that cfitsio uses ZBLANK
     651        fits_write_key_lng(fits->fd, "ZBLANK", blank, "Value for undefined pixels", &status);
    632652        fits_set_imgnull(fits->fd, blank, &status);
    633653        if (psFitsError(status, true, "Could not write BLANK header to file.")) {
     
    681701}
    682702
    683 bool psFitsUpdateImage(psFits* fits, const psImage* input, int x0, int y0, int z)
     703bool psFitsUpdateImage(psFits *fits, const psImage *input, int x0, int y0, int z)
     704{
     705    return psFitsUpdateImageWithMask(fits, input, NULL, 0, x0, y0, z);
     706}
     707
     708bool psFitsUpdateImageWithMask(psFits *fits, const psImage *input, const psImage *mask, psMaskType maskVal,
     709                               int x0, int y0, int z)
    684710{
    685711    PS_ASSERT_FITS_NON_NULL(fits, false);
    686712    PS_ASSERT_FITS_WRITABLE(fits, false);
    687713    PS_ASSERT_IMAGE_NON_NULL(input, false);
     714    if (mask) {
     715        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, false);
     716        PS_ASSERT_IMAGES_SIZE_EQUAL(mask, input, false);
     717    }
    688718
    689719    int status = 0;
     
    709739    psFitsFloat floatType;              // Custom floating-point convention type
    710740    psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &blank, &floatType, fits, input,
    711                                                    NULL, false); // Image to write out
     741                                                   mask, maskVal, NULL, false); // Image to write out
    712742    if (!diskImage) {
    713743        psError(PS_ERR_UNKNOWN, false, "Unable to convert image to desired disk format.");
     
    737767    }
    738768    if (cfitsioBzero != 0.0) {
    739         // p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!
    740         psAssert(bzero == 0.0 && bscale == 1.0, "impossible");
     769        psAssert(bzero == 0.0 && bscale == 1.0,
     770                 "p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!");
    741771        bscale = 1.0;
    742772        bzero = cfitsioBzero;
    743773    }
    744774    psFitsOptions *options = fits->options; // FITS I/O options
    745     psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0, "impossible");
     775    psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0,
     776             "Something's not consistent");
    746777
    747778    // Check to see if the HDU has the same datatype
  • trunk/psLib/src/fits/psFitsImage.h

    r15630 r19383  
    44 * @author Robert DeSonia, MHPCC
    55 *
    6  * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2007-11-16 01:04:56 $
     6 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2008-09-05 07:51:09 $
    88 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    99 */
     
    2323
    2424/// Return the dimensions and type of the FITS image
    25 bool psFitsImageSize(int *numCols, int *numRows, ///< Size of image
    26                      psElemType *type,  ///< Type of image
    27                      const psFits *fits, ///< FITS file pointer
    28                      psRegion region    ///< Region in the FITS image to read
     25bool psFitsImageSize(
     26    int *numCols, int *numRows,         ///< Size of image
     27    psElemType *type,                   ///< Type of image
     28    const psFits *fits,                 ///< FITS file pointer
     29    psRegion region                     ///< Region in the FITS image to read
    2930    );
    3031
     
    3334 *  @return psImage*     the read image or NULL if there was an error.
    3435 */
    35 psImage* psFitsReadImage(
    36     const psFits* fits,                ///< the psFits object
    37     psRegion region,                   ///< the region in the FITS image to read
    38     int z                              ///< the z-plane in the FITS image cube to read
     36psImage *psFitsReadImage(
     37    const psFits *fits,                 ///< the psFits object
     38    psRegion region,                    ///< the region in the FITS image to read
     39    int z                               ///< the z-plane in the FITS image cube to read
    3940);
    4041
    41 // Read an image into an extant buffer
    42 psImage* psFitsReadImageBuffer(psImage *output, // Output image buffer
    43                                const psFits *fits,    // the psFits object
    44                                psRegion region, // the region in the FITS image to read
    45                                int z           // the z-plane in the FITS image cube to read
    46                               );
     42/** Read an image into an extant buffer
     43 */
     44psImage *psFitsReadImageBuffer(
     45    psImage *output,                    ///< Output image buffer
     46    const psFits *fits,                 ///< the psFits object
     47    psRegion region,                    ///< the region in the FITS image to read
     48    int z                               ///< the z-plane in the FITS image cube to read
     49    );
    4750
    48 /** Writes an image, given the desired region and z-plane.
     51/** Writes an image to a FITS file
     52 *
     53 * A new IMAGE HDU is appended to the end of the FITS file.
    4954 *
    5055 *  @return bool        TRUE is the write was successful, otherwise FALSE.
    5156 */
    5257bool psFitsWriteImage(
    53     psFits* fits,                      ///< the psFits object
    54     psMetadata* header,                 ///< header items for the new HDU.  Can be NULL.
    55     const psImage* input,              ///< the image to output
    56     int depth,                         ///< the number of z-planes of the FITS image data cube
    57     const char* extname                ///< FITS extension name
     58    psFits *fits,                       ///< the psFits object
     59    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
     60    const psImage *input,               ///< the image to output
     61    int depth,                          ///< the number of z-planes of the FITS image data cube
     62    const char *extname                 ///< FITS extension name
    5863);
    5964
    60 /** Writes an image, given the desired region and z-plane.  A new IMAGE HDU is
    61  *  appended to the end of the FITS file.
     65/** Writes an image to a FITS file, optionally using the supplied mask image to do statistics when compressing
     66 *
     67 * A new IMAGE HDU is appended to the end of the FITS file.
     68 *
     69 *  @return bool        TRUE is the write was successful, otherwise FALSE.
     70 */
     71bool psFitsWriteImageWithMask(
     72    psFits *fits,                       ///< the psFits object
     73    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
     74    const psImage *input,               ///< the image to output
     75    const psImage *mask,                ///< the mask image
     76    psMaskType maskVal,                 ///< value to mask
     77    int depth,                          ///< the number of z-planes of the FITS image data cube
     78    const char *extname                 ///< FITS extension name
     79);
     80
     81/** Insert an image in a FITS file
    6282 *
    6383 *  @return bool        TRUE is the write was successful, otherwise FALSE.
    6484 */
    6585bool psFitsInsertImage(
    66     psFits* fits,                      ///< the psFits object
    67     psMetadata* header,                 ///< header items for the new HDU.  Can be NULL.
    68     const psImage* input,              ///< the image to output
    69     int depth,                         ///< the number of z-planes of the FITS image data cube
    70     const char* extname,               ///< FITS extension name
    71     bool after                         ///< if TRUE, inserts HDU after current HDU, otherwise before
     86    psFits *fits,                       ///< the psFits object
     87    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
     88    const psImage *input,               ///< the image to output
     89    int depth,                          ///< the number of z-planes of the FITS image data cube
     90    const char *extname,                ///< FITS extension name
     91    bool after                          ///< if TRUE, inserts HDU after current HDU, otherwise before
    7292);
    7393
    74 /** Updates the FITS file image, given the desired region and z-plane. a new
    75  *  IMAGE HDU is inserted before or after, depending on the AFTER parameter,
    76  *  the current HDU.
     94/** Insert an image in a FITS file, optionally using the supplied mask image to do statistics when compressing
     95 *
     96 *  @return bool        TRUE is the write was successful, otherwise FALSE.
     97 */
     98bool psFitsInsertImageWithMask(
     99    psFits *fits,                       ///< the psFits object
     100    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
     101    const psImage *input,               ///< the image to output
     102    const psImage *mask,                ///< the mask image
     103    psMaskType maskVal,                 ///< value to mask
     104    int depth,                          ///< the number of z-planes of the FITS image data cube
     105    const char *extname,                ///< FITS extension name
     106    bool after                          ///< if TRUE, inserts HDU after current HDU, otherwise before
     107);
     108
     109/** Updates an existing FITS file image
    77110 *
    78111 *  @return bool        TRUE is the write was successful, otherwise FALSE.
    79112 */
    80113bool psFitsUpdateImage(
    81     psFits* fits,                      ///< the psFits object
    82     const psImage* input,              ///< the image to output
    83     int x0,                            ///< psImage's x-axis origin in FITS image coordinates
    84     int y0,                            ///< psImage's y-axis origin in FITS image coordinates
    85     int z                              ///< the z-planes of the FITS image data cube to write
     114    psFits *fits,                       ///< the psFits object
     115    const psImage *input,               ///< the image to output
     116    int x0,                             ///< psImage's x-axis origin in FITS image coordinates
     117    int y0,                             ///< psImage's y-axis origin in FITS image coordinates
     118    int z                               ///< the z-planes of the FITS image data cube to write
     119);
     120
     121/** Updates an existing FITS file image, optionally using the supplied mask image to do statistics when
     122 ** compressing
     123 *
     124 *  @return bool        TRUE is the write was successful, otherwise FALSE.
     125 */
     126bool psFitsUpdateImageWithMask(
     127    psFits *fits,                       ///< the psFits object
     128    const psImage *input,               ///< the image to output
     129    const psImage *mask,                ///< the mask image
     130    psMaskType maskVal,                 ///< value to mask
     131    int x0,                             ///< psImage's x-axis origin in FITS image coordinates
     132    int y0,                             ///< psImage's y-axis origin in FITS image coordinates
     133    int z                               ///< the z-planes of the FITS image data cube to write
    86134);
    87135
    88136psArray *psFitsReadImageCube(const psFits *fits, psRegion region);
     137
    89138bool psFitsWriteImageCube(psFits *fits, psMetadata *header, const psArray *input, const char *extname);
     139
    90140bool psFitsUpdateImageCube(psFits *fits, const psArray *input, int x0, int y0);
    91141
  • trunk/psLib/src/fits/psFitsScale.c

    r18156 r19383  
    1313#include "psTrace.h"
    1414
     15#include "psImage.h"
    1516#include "psFits.h"
    1617#include "psImageBackground.h"
     
    9899                       double *bzero, // Zero point, to return
    99100                       const psImage *image, // Image to scale
     101                       const psImage *mask, // Mask image
     102                       psMaskType maskVal, // Value to mask
    100103                       const psFitsOptions *options // FITS options
    101104    )
     
    112115    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, seed);
    113116    psStats *stats = psStatsAlloc(MEAN_STAT | STDEV_STAT); // Statistics object
    114     if (!psImageBackground(stats, NULL, image, NULL, 0, rng)) {
     117    if (!psImageBackground(stats, NULL, image, mask, maskVal, rng)) {
    115118        psError(PS_ERR_UNKNOWN, false, "Unable to perform statistics on image");
    116119        psFree(rng);
     
    163166//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    164167
    165 bool psFitsScaleDetermine(double *bscale, // Scaling, to return
    166                           double *bzero, // Zero point, to return
    167                           long *blank,  // Blank value, to return
    168                           const psImage *image, // Image to scale
    169                           const psFits *fits // FITS options
    170     )
     168bool psFitsScaleDetermine(double *bscale, double *bzero, long *blank, const psImage *image,
     169                          const psImage *mask, psMaskType maskVal, const psFits *fits)
    171170{
    172171    PS_ASSERT_PTR_NON_NULL(bscale, false);
     
    174173    PS_ASSERT_PTR_NON_NULL(blank, false);
    175174    PS_ASSERT_IMAGE_NON_NULL(image, false);
     175    if (mask) {
     176        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, false);
     177        PS_ASSERT_IMAGES_SIZE_EQUAL(mask, image, false);
     178    }
    176179    PS_ASSERT_FITS_NON_NULL(fits, false);
    177180
     
    216219      case PS_FITS_SCALE_STDEV_NEGATIVE:
    217220      case PS_FITS_SCALE_STDEV_BOTH:
    218         if (!scaleStdev(bscale, bzero, image, options)) {
     221        if (!scaleStdev(bscale, bzero, image, mask, maskVal, options)) {
    219222            psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
    220223            return false;
  • trunk/psLib/src/fits/psFitsScale.h

    r17660 r19383  
    1212                          long *blank,  ///< Blank value, to return
    1313                          const psImage *image, ///< Image to scale
     14                          const psImage *mask, ///< Mask image
     15                          psMaskType maskVal, ///< Value to mask
    1416                          const psFits *fits ///< FITS options
    1517    );
Note: See TracChangeset for help on using the changeset viewer.