IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 18, 2008, 3:04:13 PM (19 years ago)
Author:
Paul Price
Message:

Moving all options on FITS I/O into an additional structure, psFitsOptions. The idea is that this can be carried around independently of the FITS structure, which is only created when opening a file.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/pap_branch_080117/psLib/src/fits/psFitsScale.c

    r16131 r16141  
    55#include <stdio.h>
    66#include <assert.h>
     7#include <string.h>
    78
    89#include "psAbort.h"
     
    2122
    2223// Remember:
    23 // TRUE(MEMORY) = BZERO + BSCALE * FITS(DISK)
     24// TRUE(i.e., value in memory) = BZERO + BSCALE * FITS(i.e., value on disk)
    2425
    2526
     
    3637                       double *bzero, // Zero point, to return
    3738                       const psImage *image, // Image to scale
    38                        const psFits *fits // FITS options
     39                       const psFitsOptions *options // FITS options
    3940    )
    4041{
     
    4243    assert(bzero);
    4344    assert(image);
    44     assert(fits);
    45 
    46     double range = pow(2.0, fits->bitpix); // Range of values for target BITPIX
     45    assert(options);
     46
     47    double range = pow(2.0, options->bitpix); // Range of values for target BITPIX
    4748    double min = INFINITY, max = -INFINITY; // Minimum and maximum values
    4849    int numCols = image->numCols, numRows = image->numRows; // Size of image
     
    9697                       double *bzero, // Zero point, to return
    9798                       const psImage *image, // Image to scale
    98                        const psFits *fits // FITS options
     99                       const psFitsOptions *options // FITS options
    99100    )
    100101{
     
    102103    assert(bzero);
    103104    assert(image);
    104     assert(fits);
    105 
    106     double mean = fits->mean, stdev = fits->stdev; // Mean and standard deviation
     105    assert(options);
     106
     107    double mean = options->mean, stdev = options->stdev; // Mean and standard deviation
    107108    if (!isfinite(mean) || !isfinite(stdev)) {
    108109        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     
    112113    }
    113114
    114     long range = 1 << fits->stdevBits;  // Range of values to carry standard deviation
     115    long range = 1 << options->stdevBits;  // Range of values to carry standard deviation
    115116    *bscale = stdev / (double) range;
    116117
    117     int bitpix = fits->bitpix;          // Bits per pixel
    118118    double imageVal;                    // Value on image
    119119    long diskVal;                       // Corresponding value on disk
    120     switch (fits->scaling) {
     120    switch (options->scaling) {
    121121      case PS_FITS_SCALE_STDEV_POSITIVE:
    122122        // Put (mean - N sigma) at the lowest possible value: predominantly positive images
    123         imageVal = mean - fits->stdevNum * stdev;
    124         diskVal = - (1 << (bitpix - 1));
     123        imageVal = mean - options->stdevNum * stdev;
     124        diskVal = - (1 << (options->bitpix - 1));
    125125        break;
    126126      case PS_FITS_SCALE_STDEV_NEGATIVE:
    127127        // Put (mean + N sigma) at the highest possible value: predominantly negative images
    128         imageVal = mean + fits->stdevNum * stdev;
    129         diskVal = (1 << (bitpix - 1)) - 1;
     128        imageVal = mean + options->stdevNum * stdev;
     129        diskVal = (1 << (options->bitpix - 1)) - 1;
    130130        break;
    131131      case PS_FITS_SCALE_STDEV_BOTH:
     
    165165    // If we don't have a RNG, we will allocate one
    166166
    167     if (fits->scaling != PS_FITS_SCALE_STDEV_POSITIVE &&
    168         fits->scaling != PS_FITS_SCALE_STDEV_NEGATIVE &&
    169         fits->scaling != PS_FITS_SCALE_STDEV_BOTH) {
     167    psFitsOptions *options = fits->options; // FITS options
     168    if (!options) {
     169        // No scaling desired
     170        return true;
     171    }
     172
     173    if (options->scaling != PS_FITS_SCALE_STDEV_POSITIVE &&
     174        options->scaling != PS_FITS_SCALE_STDEV_NEGATIVE &&
     175        options->scaling != PS_FITS_SCALE_STDEV_BOTH) {
    170176        // No need to do anything
    171177        return true;
     
    186192    psFree(rng);
    187193
    188     fits->mean = psStatsGetValue(stats, MEAN_STAT); // Mean
    189     fits->stdev = psStatsGetValue(stats, STDEV_STAT); // Standard deviation
     194    options->mean = psStatsGetValue(stats, MEAN_STAT); // Mean
     195    options->stdev = psStatsGetValue(stats, STDEV_STAT); // Standard deviation
    190196    psFree(stats);
    191197
     
    208214    *bzero = 0.0;
    209215
    210     if (!PS_IS_PSELEMTYPE_REAL(image->type.type)) {
     216    psFitsOptions *options = fits->options; // FITS options
     217    if (!PS_IS_PSELEMTYPE_REAL(image->type.type) || !options) {
    211218        return true;
    212219    }
    213220
    214     switch (fits->bitpix) {
     221    switch (options->bitpix) {
    215222      case 0:
    216223        // No scaling applied
     
    224231      default:
    225232        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Target bitpix (%d) is not one of 0,8,16,32,64",
    226                 fits->bitpix);
     233                options->bitpix);
    227234        return false;
    228235    }
    229236
    230     switch (fits->scaling) {
     237    switch (options->scaling) {
    231238      case PS_FITS_SCALE_NONE:
    232239        // No scaling applied
    233240        break;
    234241      case PS_FITS_SCALE_RANGE:
    235         if (!scaleRange(bscale, bzero, image, fits)) {
     242        if (!scaleRange(bscale, bzero, image, options)) {
    236243            psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from range");
    237244            return false;
     
    241248      case PS_FITS_SCALE_STDEV_NEGATIVE:
    242249      case PS_FITS_SCALE_STDEV_BOTH:
    243         if (!scaleStdev(bscale, bzero, image, fits)) {
     250        if (!scaleStdev(bscale, bzero, image, options)) {
    244251            psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
    245252            return false;
     
    247254        break;
    248255      case PS_FITS_SCALE_MANUAL:
    249         *bscale = fits->bscale;
    250         *bzero = fits->bzero;
    251         break;
    252       default:
    253         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unrecognised FITS scaling option: %x", fits->scaling);
     256        *bscale = options->bscale;
     257        *bzero = options->bzero;
     258        break;
     259      default:
     260        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unrecognised FITS scaling method: %x",
     261                options->scaling);
    254262        return false;
    255263    }
     
    260268
    261269
    262 psImage *psFitsScaleForDisk(const psImage *image, int bitpix, double bscale, double bzero, bool fuzz,
     270psImage *psFitsScaleForDisk(const psImage *image, const psFits *fits, double bscale, double bzero,
    263271                            psRandom *rng)
    264272{
    265273    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
    266 
    267     if (!PS_IS_PSELEMTYPE_REAL(image->type.type) || bitpix == 0) {
     274    PS_ASSERT_FITS_NON_NULL(fits, NULL);
     275
     276    psFitsOptions *options = fits->options; // FITS options
     277    if (!PS_IS_PSELEMTYPE_REAL(image->type.type) || !options || options->bitpix == 0) {
     278        // No scaling desired
    268279        return psMemIncrRefCounter((psImage*)image); // Casting away "const"
    269280    }
    270281
     282    int bitpix = options->bitpix;       // Bits per pixel
    271283    psElemType outType;                 // Type for output image
    272284    // Choosing to use signed types because those don't require BSCALE,BZERO to represent them in the FITS
     
    290302    }
    291303
    292     if (bscale == 1.0 && bzero == 0.0) {
     304    if (bscale == 1.0 && bzero == 0.0 && !options->fuzz) {
    293305        return psImageCopy(NULL, image, outType);
    294306    }
     
    297309    psImage *out = psImageAlloc(numCols, numRows, outType); // Output image
    298310
    299     if (!psMemIncrRefCounter(rng) && fuzz) {
     311    if (!psMemIncrRefCounter(rng) && options->fuzz) {
    300312        // Don't blab about which seed we're going to get --- it's not necessary for this purpose
    301313        psU64 seed = p_psRandomGetSystemSeed(false);
     
    307319        ps##INTYPE scale = 1.0 / bscale; \
    308320        ps##INTYPE zero = bzero; \
    309         if (fuzz) { \
     321        if (options->fuzz) { \
    310322            /* Add random factor [0,1): adds a variance of 1/12, but preserves the expectation value */ \
    311323            for (int y = 0; y < numRows; y++) { \
     
    435447}
    436448#endif
     449
     450
     451
     452psFitsScaling psFitsScalingFromString(const char *string)
     453{
     454    PS_ASSERT_STRING_NON_EMPTY(string, PS_FITS_SCALE_NONE);
     455
     456    if (strcasecmp(string, "RANGE") == 0)          return PS_FITS_SCALE_RANGE;
     457    if (strcasecmp(string, "STDEV_POSITIVE") == 0) return PS_FITS_SCALE_STDEV_POSITIVE;
     458    if (strcasecmp(string, "STDEV_NEGATIVE") == 0) return PS_FITS_SCALE_STDEV_NEGATIVE;
     459    if (strcasecmp(string, "STDEV_BOTH") == 0)     return PS_FITS_SCALE_STDEV_BOTH;
     460    if (strcasecmp(string, "MANUAL") == 0)         return PS_FITS_SCALE_MANUAL;
     461
     462    psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to interpret FITS scaling: %s", string);
     463    return PS_FITS_SCALE_NONE;
     464}
     465
     466
Note: See TracChangeset for help on using the changeset viewer.