IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31656


Ignore:
Timestamp:
Jun 21, 2011, 6:44:31 PM (15 years ago)
Author:
eugene
Message:

merge from trunk

Location:
branches/eam_branches/ipp-20110505
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110505/ippScripts/scripts/ipp_apply_burntool_single.pl

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • branches/eam_branches/ipp-20110505/ippScripts/scripts/nightly_science.pl

    r31421 r31656  
    6060    'test_mode'            => \$test_mode,
    6161    'force_stack_count'    => \$force_stack_count,
    62     'force_diff_count'    => \$force_diff_count,
     62    'force_diff_count'     => \$force_diff_count,
    6363    'this_target_only=s'   => \$this_target_only,
    6464    'this_filter_only=s'   => \$this_filter_only,
     
    865865# }
    866866
    867 # sub get_lunation_extent {
    868 #     my $date = shift;
    869 #     my ($year,$month,$day) = split /-/,$date;
    870 #     my $dateobs_begin;
    871 #     my $dateobs_end;
    872 
    873 #     my $dt = DateTime->new(year => $year, month => $month, day => $day,
    874 #                          hour => 0, minute => 0, second => 0, nanosecond => 0,
    875 #                          time_zone => 'Pacific/Honolulu');
    876 #     do {
    877 #       $dt->subtract(days => 1);
    878 #       my $ymd = $dt->ymd;
    879 #       my $md_cmd = "moondata $ymd 0 0";
    880 #       my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    881 #           run ( command => $md_cmd, verbose => $verbose);
    882 #       unless ($success) {
    883 #           $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
    884 #           &my_die("Unable to perform moondata: $error_code", 0,0, $date, $PS_EXIT_SYS_ERROR);
    885 #       }
    886 #       my @result = split /\s+/,(join "\n", @$stdout_buf);
    887 #       if (abs($result[6]) <= 0.5) {
    888 #           $dateobs_end = $ymd;
    889 #       }
    890 #     } while (!defined($dateobs_end));
    891    
    892 #     do {
    893 #       $dt->subtract(days => 1);
    894 #       my $ymd = $dt->ymd;
    895 #       my $md_cmd = "moondata $ymd 0 0";
    896 #       my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    897 #           run ( command => $md_cmd, verbose => $verbose);
    898 #       unless ($success) {
    899 #           $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
    900 #           &my_die("Unable to perform moondata: $error_code", 0,0, $date, $PS_EXIT_SYS_ERROR);
    901 #       }
    902 #       my @result = split /\s+/,(join "", @$stdout_buf);
    903 #       if (abs($result[6]) <= 0.5) {
    904 #           $dateobs_begin = $ymd;
    905 #       }
    906 #     } while (!defined($dateobs_begin));
     867sub get_lunation_extent {
     868    my $date = shift;
     869    my ($year,$month,$day) = split /-/,$date;
     870    my $dateobs_begin;
     871    my $dateobs_end;
     872
     873    my $dt = DateTime->new(year => $year, month => $month, day => $day,
     874                           hour => 0, minute => 0, second => 0, nanosecond => 0,
     875                           time_zone => 'Pacific/Honolulu');
     876    do {
     877        $dt->add(days => 1);
     878        my $ymd = $dt->ymd;
     879        my $md_cmd = "moondata $ymd 0 0";
     880        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     881            run ( command => $md_cmd, verbose => $verbose);
     882        unless ($success) {
     883            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
     884            &my_die("Unable to perform moondata: $error_code", 0,0, $date, $PS_EXIT_SYS_ERROR);
     885        }
     886        my @result = split /\s+/,(join "\n", @$stdout_buf);
     887        if (abs($result[6]) <= 0.6) {
     888            $dateobs_end = $ymd;
     889        }
     890    } while (!defined($dateobs_end));
     891   
     892    do {
     893        $dt->subtract(days => 1);
     894        my $ymd = $dt->ymd;
     895        my $md_cmd = "moondata $ymd 0 0";
     896        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     897            run ( command => $md_cmd, verbose => $verbose);
     898        unless ($success) {
     899            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
     900            &my_die("Unable to perform moondata: $error_code", 0,0, $date, $PS_EXIT_SYS_ERROR);
     901        }
     902        my @result = split /\s+/,(join "", @$stdout_buf);
     903        if (abs($result[6]) <= 0.6) {
     904            $dateobs_begin = $ymd;
     905        }
     906    } while (!defined($dateobs_begin));
    907907       
    908 #     return($dateobs_begin,$dateobs_end);
    909 # }
     908    return($dateobs_begin,$dateobs_end);
     909}
    910910
    911911# sub pre_sweetspot_queue {
     
    14051405                }
    14061406            }
    1407         }
    1408     }
     1407            if ((defined($science_config{$target}{OFFNIGHT_DIFFS})) && ($science_config{$target}{OFFNIGHT_DIFFS} == 1)) {
     1408                foreach my $filter (@filter_list) {
     1409                    offnight_diff_queue($date,$target,$filter,$pretend);
     1410                }
     1411            }
     1412        }
     1413    }
     1414
    14091415#     if (($Npotential == $Nnoexp)&&($metadata_out{nsObservingState} eq 'END_OF_NIGHT')&&($is_processing == 0)) {
    14101416#       $metadata_out{nsDiffState} = 'FINISHED_DIFFS';
     
    16821688
    16831689}
     1690
     1691sub offnight_diff_queue {
     1692    my $date = shift;
     1693    my $target = shift;
     1694    my $filter = shift;
     1695    my $pretend = shift;
     1696    my ($label,$workdir,$obs_mode,$object,$comment,$tess_id,$dist_group,$data_group,$reduction) = get_tool_parameters($date,$target);
     1697
     1698    my $db = init_gpc_db();
     1699
     1700#    my $Npotential = 0;
     1701#    my $Nqueued = 0;
     1702
     1703    my ($lunation_start,$lunation_end) = get_lunation_extent($date);
     1704   
     1705    my $new_data_group = "${data_group}.offnight";
     1706    my $new_dist_group = "${dist_group}.offnight";
     1707    my $cmd = "$difftool -dbname $dbname  -definewarpwarp ";
     1708    $cmd .= "-input_label $label  -template_label $label ";
     1709    $cmd .= "-set_workdir $workdir  -set_dist_group $new_dist_group  -set_data_group $new_data_group ";
     1710    $cmd .= " -simple  -set_label $label -filter $filter ";
     1711    $cmd .= " -dateobs_begin ${lunation_start}T00:00:00 -dateobs_end ${lunation_end}T23:59:59 -distance 1.5 ";
     1712
     1713    if (defined($pretend)) {
     1714        $cmd .= ' -pretend ';
     1715    }
     1716    if (defined($debug)) {
     1717        print STDERR "ON_diffs wants to run this command: $cmd\n";
     1718    }
     1719   
     1720    if (($debug == 0)&&(!defined($pretend))) {
     1721        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     1722            run ( command => $cmd, verbose => $verbose );
     1723        unless ($success) {
     1724            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
     1725            &my_die("Unable to perform difftool: $error_code", 0,0,$date, $PS_EXIT_SYS_ERROR);
     1726        }
     1727    }
     1728}
    16841729           
    16851730
  • branches/eam_branches/ipp-20110505/ippTasks/diskbalance.pro

    r30933 r31656  
    9393$BALANCE_SO_ID_START = int($BALANCE_BIG_SO_ID * rnd(0))
    9494$BALANCE_SO_ID_RANGE = 500000
    95 
     95$BALANCE_LIMIT       = 500
     96$BALANCE_OFFSET      = 0
    9697# Select Nebulous objects which should be shuffled
    9798task           balance.load
    9899  host         local
    99100
    100   periods      -poll 0.5
    101   periods      -exec 5
     101  periods      -poll 60
     102  periods      -exec 60
    102103  periods      -timeout 1500
    103104  npending     1
     
    117118    book getword balanceControl control mDestinations -var BALANCE_M
    118119
    119     command neb-admin --host $NEB_HOST --db $NEB_DB --user $NEB_USER --pass $NEB_PASS --pendingbalance --limit 500 --so_id_start $BALANCE_SO_ID_START --so_id_range $BALANCE_SO_ID_RANGE  --balancesources $BALANCE_N --balancedestination $BALANCE_M
     120    command neb-admin --host $NEB_HOST --db $NEB_DB --user $NEB_USER --pass $NEB_PASS --pendingbalance --limit $BALANCE_LIMIT --offset $BALANCE_OFFSET --so_id_start $BALANCE_SO_ID_START --so_id_range $BALANCE_SO_ID_RANGE  --balancesources $BALANCE_N --balancedestination $BALANCE_M
    120121
    121122  end
     
    125126    # advance the so_id counter
    126127    $BALANCE_SO_ID_START = $BALANCE_SO_ID_START + $BALANCE_SO_ID_RANGE
    127 
     128    $BALANCE_OFFSET = 0
    128129    # convert 'stdout' to book format
    129130    ipptool2book stdout balancePending -key key -uniq -setword pantaskState INIT
     
    141142    # convert 'stdout' to book format
    142143    ipptool2book stdout balancePending -key key -uniq -setword pantaskState INIT
    143 
     144    $BALANCE_OFFSET = $BALANCE_OFFSET + $BALANCE_LIMIT
    144145    if ($VERBOSE > 2)
    145146      book listbook balancePending
  • branches/eam_branches/ipp-20110505/ippTools/share/camtool_find_pendingimfile.sql

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • branches/eam_branches/ipp-20110505/ippTools/share/pxadmin_create_tables.sql

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • branches/eam_branches/ipp-20110505/ippTools/src

  • branches/eam_branches/ipp-20110505/ippTools/src/magictool.c

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • branches/eam_branches/ipp-20110505/ippTools/src/stacktool.c

    r31587 r31656  
    243243    PXOPT_COPY_STR(config->args,  where, "-select_exp_type",           "rawExp.exp_type", "==");
    244244    PXOPT_COPY_F32(config->args,  where, "-select_good_frac_min",      "warpSkyfile.good_frac", ">=");
    245     PXOPT_COPY_STR(config->args,  where, "-select_skycell_id",         "warpSkyfile.skycell_id", "LIKE");
    246     PXOPT_COPY_STR(config->args,  where, "-select_data_group",         "warpRun.data_group", "==");
     245    pxAddLabelSearchArgs(config,  where, "-select_skycell_id",         "warpSkyfile.skycell_id", "LIKE");
     246    pxAddLabelSearchArgs(config,  where, "-select_data_group",         "warpRun.data_group", "LIKE");
    247247    pxAddLabelSearchArgs (config, where, "-select_label",              "warpRun.label", "LIKE"); // define using warp label
    248248    pxAddLabelSearchArgs (config, where, "-warp_id",                   "warpRun.warp_id", "==");
  • branches/eam_branches/ipp-20110505/ippTools/src/stacktoolConfig.c

    r31587 r31656  
    5555    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_dvodb", 0, "define dvodb", NULL);
    5656    psMetadataAddTime(definebyqueryArgs, PS_LIST_TAIL, "-set_registered", 0, "time detrend run was registered", now);
    57     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_skycell_id", 0, "search for skycell_id", NULL);
     57    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_skycell_id", PS_META_DUPLICATE_OK, "search for skycell_id (LIKE comparison, multiple ok)", NULL);
    5858    psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-select_good_frac_min", 0, "define min good_frac", 0.0);
    5959    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_exp_type", 0, "search for exp_type", "object");
    6060    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_label", PS_META_DUPLICATE_OK, "search by warpRun label (LIKE comparison, multiple OK)", NULL);
    61     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_data_group", 0 , "search by warpRun data_group", NULL);
     61    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_data_group", PS_META_DUPLICATE_OK , "search by warpRun data_group (LIKE comparison, multiple ok)", NULL);
    6262    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_comment", 0, "search for comment (LIKE)", NULL);
    6363    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_inst", 0, "search for camera", NULL);
  • branches/eam_branches/ipp-20110505/psLib/src/fits/psFits.h

    r30636 r31656  
    5555    PS_FITS_SCALE_LOG_STDEV_NEGATIVE,   ///< Take logarithm, Auto-scale to sample stdev, place mean at upper limit
    5656    PS_FITS_SCALE_LOG_STDEV_BOTH,       ///< Take logarithm, Auto-scale to sample stdev, place mean at middle
    57     PS_FITS_SCALE_LOG_MANUAL            ///< Manual scaling (use specified BSCALE, BZERO, and BOFFSET)
     57    PS_FITS_SCALE_LOG_MANUAL,           ///< Manual scaling (use specified BSCALE, BZERO, and BOFFSET)
     58    PS_FITS_SCALE_ASINH_RANGE,          ///< Do asinh scaling, auto-scale to preserve dynamic range
     59    PS_FITS_SCALE_ASINH_STDEV_POSITIVE, ///< Do asinh scaling, auto-scale to sample stdev, place mean at lower limit
     60    PS_FITS_SCALE_ASINH_STDEV_NEGATIVE, ///< Do asinh scaling, auto-scale to sample stdev, place mean at upper limit
     61    PS_FITS_SCALE_ASINH_STDEV_BOTH,     ///< Do asinh scaling, auto-scale to sample stdev, place mean at middle
     62    PS_FITS_SCALE_ASINH_MANUAL          ///< Manual scaling after doing asinh scaling.
    5863} psFitsScaling;
    5964
     
    7277    double bscale, bzero;               ///< Manually specified BSCALE and BZERO (for SCALE_MANUAL)
    7378    double boffset;                     ///< Manually specified BOFFSET (for SCALE_MANUAL)
     79    double bsoften;                     ///< Manuallly specified BSOFTEN (for SCALE_MANUAL)
    7480    double mean, stdev;                 ///< Mean and standard deviation of image
    7581    int stdevBits;                      ///< Number of bits to sample a standard deviation (for SCALE_STDEV_*)
  • branches/eam_branches/ipp-20110505/psLib/src/fits/psFitsImage.c

    r31608 r31656  
    5555    int psDatatype;                     // psLib data type
    5656    bool is_logscaled;                  // is this image log scaled using BOFFSET?
     57    bool is_asinh;                      // is this image asinh scaled using BSOFTEN?
    5758} p_psFitsReadInfo;
    5859
     
    129130
    130131    // Check scale and zero
    131     double bscale = 0.0, bzero = 0.0, boffset = NAN;    // Scale and zero point
     132    double bscale = 0.0, bzero = 0.0, boffset = NAN, bsoften = NAN;    // Scale and zero point
    132133    if (fits_read_key_dbl(fits->fd, "BSCALE", &bscale, NULL, &status) && status != KEY_NO_EXIST) {
    133134        psFitsError(status, true, "Unable to read header.");
     
    153154      info->is_logscaled = false;
    154155    }
     156    status = 0;
     157    if (fits_read_key_dbl(fits->fd, "BSOFTEN", &bsoften, NULL, &status) && status != KEY_NO_EXIST) {
     158        psFitsError(status, true, "Unable to read header.");
     159        goto bad;
     160    }
     161    if (status == KEY_NO_EXIST) {
     162      info->is_asinh = false;
     163    }
     164    else if (isfinite(bsoften)) {
     165      info->is_asinh = true;
     166      info->is_logscaled = false;
     167    }
     168    else {
     169      info->is_asinh = false;
     170    }
     171
    155172    status = 0;
    156173
     
    262279                                          double *bzero, // Zero point applied
    263280                                          double *boffset, // Log offset applied
     281                                          double *bsoften, // asinh offset applied
    264282                                          long *blank, // Blank value (integer data)
    265283                                          psFitsFloat *floatType, // Type of custom floating-point
     
    275293    psAssert(bzero, "impossible");
    276294    psAssert(boffset, "impossible");
     295    psAssert(bsoften, "impossible");
    277296    psAssert(floatType, "impossible");
    278297    psAssert(fits, "impossible");
     
    322341        if (newScaleZero) {
    323342            // Choose an appropriate BSCALE and BZERO
    324           if (!psFitsScaleDetermine(bscale, bzero, boffset, blank, image, mask, maskVal, fits)) {
     343          if (!psFitsScaleDetermine(bscale, bzero, boffset, bsoften, blank, image, mask, maskVal, fits)) {
    325344                // We can't have the write dying for this reason --- try to save it somehow!
    326345                psWarning("Unable to determine BSCALE and BZERO for image --- refusing to quantise.");
     
    348367        }
    349368
    350         return psFitsScaleForDisk(image, fits, *bscale, *bzero, *boffset, rng);
     369        return psFitsScaleForDisk(image, fits, *bscale, *bzero, *boffset, *bsoften, rng);
    351370    }
    352371
     
    480499        outImage = psFitsFloatImageFromDisk(outImage, inImage, floatType);
    481500    }
    482 
    483501    // Need to apply BOFFSET if info->is_logscaled is true
     502
    484503    if (info->is_logscaled) {
    485504      double boffset;
     
    487506      status = 0;
    488507      fits_read_key_dbl(fits->fd, "BOFFSET", &boffset, NULL, &status);
    489       psImage *newImage = psFitsScaleFromDisk(outImage,boffset);
     508      psImage *newImage = psFitsScaleFromDisk(outImage,boffset,0.0);
     509      psFree (outImage);
     510      outImage = newImage;
     511    }
     512    else if (info->is_asinh) {
     513      double bsoften,boffset;
     514      int status;
     515      status = 0;
     516      fits_read_key_dbl(fits->fd, "BSOFTEN", &bsoften, NULL, &status);
     517      fits_read_key_dbl(fits->fd, "BOFFSET", &boffset, NULL, &status);
     518      psImage *newImage = psFitsScaleFromDisk(outImage,boffset,bsoften);
    490519      psFree (outImage);
    491520      outImage = newImage;
     
    602631    double bscale = NAN, bzero = NAN;   // Scale and zero point to put in header
    603632    double boffset = NAN;               // Log offset to put into header.
     633    double bsoften = NAN;               // Asinh softening parameter to put into header
    604634    long blank = 0;                     // Blank (undefined) value for image
    605635    psFitsFloat floatType;              // Custom floating-point convention type
    606     psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &boffset, &blank, &floatType, fits, image,
     636    psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &boffset, &bsoften, &blank, &floatType, fits, image,
    607637                                                   mask, maskVal, NULL, true); // Image to write out
    608638    if (!diskImage) {
     
    696726    if (options&&(!((options->scaling == PS_FITS_SCALE_LOG_RANGE)||
    697727                    (options->scaling == PS_FITS_SCALE_LOG_MANUAL)||
    698                    (options->scaling == PS_FITS_SCALE_LOG_STDEV_POSITIVE)||
    699                    (options->scaling == PS_FITS_SCALE_LOG_STDEV_NEGATIVE)||
    700                    (options->scaling == PS_FITS_SCALE_LOG_STDEV_BOTH)))) {
     728                    (options->scaling == PS_FITS_SCALE_LOG_STDEV_POSITIVE)||
     729                    (options->scaling == PS_FITS_SCALE_LOG_STDEV_NEGATIVE)||
     730                    (options->scaling == PS_FITS_SCALE_LOG_STDEV_BOTH)||
     731                    (options->scaling == PS_FITS_SCALE_ASINH_RANGE)||
     732                    (options->scaling == PS_FITS_SCALE_ASINH_MANUAL)||
     733                    (options->scaling == PS_FITS_SCALE_ASINH_STDEV_POSITIVE)||
     734                    (options->scaling == PS_FITS_SCALE_ASINH_STDEV_NEGATIVE)||
     735                    (options->scaling == PS_FITS_SCALE_ASINH_STDEV_BOTH)))) {
    701736      if (psMetadataLookup(header,"BOFFSET")) {
    702737        psMetadataRemoveKey(header,"BOFFSET");
     738      }
     739    }   
     740    // Remove any BSOFTENvalues that exist in the header if we are not using that scaling anymore
     741    if (options&&(!((options->scaling == PS_FITS_SCALE_ASINH_RANGE)||
     742                    (options->scaling == PS_FITS_SCALE_ASINH_MANUAL)||
     743                    (options->scaling == PS_FITS_SCALE_ASINH_STDEV_POSITIVE)||
     744                    (options->scaling == PS_FITS_SCALE_ASINH_STDEV_NEGATIVE)||
     745                    (options->scaling == PS_FITS_SCALE_ASINH_STDEV_BOTH)))) {
     746      if (psMetadataLookup(header,"BSOFTEN")) {
     747        psMetadataRemoveKey(header,"BSOFTEN");
    703748      }
    704749    }   
     
    727772                       (options->scaling == PS_FITS_SCALE_LOG_STDEV_BOTH)))) {
    728773          fits_write_key_dbl(fits->fd, "BOFFSET", boffset, 12,
    729                              "Scaling: TRUE = BZERO + BSCALE * 10**(DISK) + BOFFSET)", &status);
     774                             "Scaling: ORIGINAL = 10**(TRUE) + BOFFSET)", &status);
    730775        }       
     776        if (options&&(((options->scaling == PS_FITS_SCALE_ASINH_RANGE)||
     777                       (options->scaling == PS_FITS_SCALE_ASINH_MANUAL)||
     778                       (options->scaling == PS_FITS_SCALE_ASINH_STDEV_POSITIVE)||
     779                       (options->scaling == PS_FITS_SCALE_ASINH_STDEV_NEGATIVE)||
     780                       (options->scaling == PS_FITS_SCALE_ASINH_STDEV_BOTH)))) {
     781          fits_write_key_dbl(fits->fd, "BOFFSET", boffset, 12,
     782                             "Scaling: NORM = DISK + BOFFSET", &status);
     783          fits_write_key_dbl(fits->fd, "BSOFTEN", bsoften, 12,
     784                             "Scaling: TRUE = 2 * BSOFTEN * sinh(NORM/a)",&status);
     785
     786
     787        }       
     788
    731789        if (psFitsError(status, true, "Could not write BSCALE/BZERO headers to file.")) {
    732790            success = false;
     
    831889    double bscale = NAN, bzero = NAN;   // Scale and zero point to put in header
    832890    double boffset = NAN;               // Log offset to put in header
     891    double bsoften = NAN;               // Asinh softening parameter to put in header
    833892    long blank = 0;                     // Blank (undefined) value for image
    834893    psFitsFloat floatType;              // Custom floating-point convention type
    835     psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &boffset, &blank, &floatType, fits, input,
     894    psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &boffset, &bsoften, &blank, &floatType, fits, input,
    836895                                                   mask, maskVal, NULL, false); // Image to write out
    837896    if (!diskImage) {
  • branches/eam_branches/ipp-20110505/psLib/src/fits/psFitsScale.c

    r30636 r31656  
    214214      case PS_FITS_SCALE_STDEV_POSITIVE:
    215215      case PS_FITS_SCALE_LOG_STDEV_POSITIVE:
     216      case PS_FITS_SCALE_ASINH_STDEV_POSITIVE:
    216217        // Put (mean - N sigma) at the lowest possible value: predominantly positive images
    217218        imageVal = mean - options->stdevNum * stdev;
     
    220221      case PS_FITS_SCALE_STDEV_NEGATIVE:
    221222      case PS_FITS_SCALE_LOG_STDEV_NEGATIVE:
     223      case PS_FITS_SCALE_ASINH_STDEV_NEGATIVE:
    222224        // Put (mean + N sigma) at the highest possible value: predominantly negative images
    223225        imageVal = mean + options->stdevNum * stdev;
     
    226228      case PS_FITS_SCALE_STDEV_BOTH:
    227229      case PS_FITS_SCALE_LOG_STDEV_BOTH:
     230      case PS_FITS_SCALE_ASINH_STDEV_BOTH:
    228231        // Put mean right in the middle: images with an equal abundance of positive and negative values
    229232        imageVal = mean;
     
    241244}
    242245
     246
     247   
    243248
    244249static bool logscaleStdev(double *bscale, // Scaling, to return
     
    456461}
    457462
     463static bool asinhStdev(double *bscale, // Scaling, to return
     464                       double *bzero,  // Zero point, to return
     465                       double *boffset, // asinh flux zeropoint, to return
     466                       double *bsoften, // asinh softening parameter, to return
     467                       const psImage *image, // Image to scale
     468                       const psImage *mask,  // Mask image
     469                       psImageMaskType maskVal, // value to mask
     470                       const psFitsOptions *options // FITS options
     471                       )
     472{
     473  psAssert(bscale, "impossible");
     474  psAssert(bzero, "impossible");
     475  psAssert(boffset, "impossible");
     476  psAssert(bsoften, "impossible");
     477  psAssert(image, "impossible");
     478  psAssert(options, "impossible");
     479
     480  psTrace("psLib.fits", 3, "Scaling image by asinh method");
     481  int numCols = image->numCols, numRows = image->numRows; // Size of image
     482 
     483    // Measure the mean and stdev
     484    // psImageBackground automatically excludes pixels that are non-finite, so we don't need to bother about a
     485    // mask.
     486    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);
     487    psStats *stats = psStatsAlloc(MEAN_STAT | STDEV_STAT); // Statistics object
     488    double mean, stdev;                                    // Mean and standard deviation
     489    if (!psImageBackground(stats, NULL, image, mask, maskVal, rng)) {
     490        // It could be because the image is entirely masked, in which case we don't want to error
     491        bool good = false;              // Any good pixels?
     492
     493
     494// Find good pixels in an image, by image type
     495#define GOOD_PIXELS_CASE(TYPE) \
     496      case PS_TYPE_##TYPE: \
     497        for (int y = 0; y < image->numRows && !good; y++) { \
     498            for (int x = 0; x < image->numCols && !good; x++) { \
     499                if (mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) { \
     500                    continue; \
     501                } \
     502                if (!isfinite(image->data.TYPE[y][x])) { \
     503                    continue; \
     504                } \
     505                good = true; \
     506            } \
     507        } \
     508        break;
     509
     510        switch (image->type.type) {
     511            GOOD_PIXELS_CASE(F32);
     512            GOOD_PIXELS_CASE(F64);
     513          default:
     514            psAbort("Unsupported case: %x", image->type.type);
     515        }
     516
     517        if (!good) {
     518            psLogMsg("psLib.fits", PS_LOG_DETAIL, "Image has no good pixels, setting BSCALE = 1, BZERO = 0");
     519            psErrorClear();
     520            *bscale = 1.0;
     521            *bzero = 0.0;
     522            *bsoften = NAN;
     523            psFree(rng);
     524            psFree(stats);
     525            return true;
     526        }
     527
     528        // There are some good pixels in there somewhere; psImageBackground just didn't find them
     529        psLogMsg("psLib.fits", PS_LOG_DETAIL,
     530                 "Couldn't measure background statistics for image quantisation; retrying.");
     531        psErrorClear();
     532        // Retry using all the available pixels
     533        stats->nSubsample = image->numCols * image->numRows + 1;
     534        if (!psImageStats(stats, image, mask, maskVal)) {
     535            psLogMsg("psLib.fits", PS_LOG_DETAIL,
     536                     "Couldn't measure background statistics for image quantisation (attempt 2); retrying.");
     537            psErrorClear();
     538            // Retry with desperate statistic
     539            stats->options = DESPERATE_MEAN_STAT | DESPERATE_STDEV_STAT;
     540            if (!psImageStats(stats, image, mask, maskVal)) {
     541                psError(PS_ERR_UNKNOWN, false, "Unable to measure background statistics for image");
     542                psFree(rng);
     543                psFree(stats);
     544                return false;
     545            } else {
     546                // Desperate retry
     547                mean = psStatsGetValue(stats, DESPERATE_MEAN_STAT);
     548                stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
     549            }
     550        } else {
     551            // Retry with all available pixels
     552            mean = psStatsGetValue(stats, MEAN_STAT);
     553            stdev = psStatsGetValue(stats, STDEV_STAT);
     554        }
     555    } else {
     556        // First attempt
     557        mean = psStatsGetValue(stats, MEAN_STAT);
     558        stdev = psStatsGetValue(stats, STDEV_STAT);
     559    }
     560    psFree(rng);
     561    psFree(stats);
     562    if (!isfinite(mean) || !isfinite(stdev)) {
     563        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     564                "Mean (%f) or stdev (%f) is non-finite.", mean, stdev);
     565        return false;
     566    }
     567
     568    psImage *copy;
     569
     570    switch (image->type.type) {
     571    case PS_TYPE_F32:
     572      copy = psImageCopy(NULL,image,PS_TYPE_F32);
     573      break;
     574    case PS_TYPE_F64:
     575      copy = psImageCopy(NULL,image,PS_TYPE_F64);
     576      break;
     577    default:
     578      psError(PS_ERR_UNKNOWN, true, "Target type is not a float: %d", image->type.type);
     579      return NULL;
     580      break;
     581    }
     582    // Do scaling
     583    float a = 1.0857362; // 2.5 * log(e);
     584    *bsoften = sqrt(a) * stdev;
     585    *boffset = mean;
     586    //    float m0 = 0; // Can I just arbitrarily set this?
     587   
     588    switch (image->type.type) {
     589    case PS_TYPE_F32:
     590      for (int y = 0; y < numRows; y++) {
     591        for (int x = 0; x < numCols; x++) {
     592/*        if (x == 266 && y == 4584) { */
     593/*          fprintf(stderr,"psFS32: %d %d %g %g %g %g %g\n",x,y,*boffset,*bsoften,image->data.F32[y][x],log10(image->data.F32[y][x] - *boffset), */
     594/*                  a * asinh((image->data.F32[y][x] - *boffset) / (2 * *bsoften))); */
     595/*        } */
     596          if (isfinite(image->data.F32[y][x])) {
     597            copy->data.F32[y][x] = a * asinh( (image->data.F32[y][x] - *boffset) / (2 * *bsoften));// - 2.5 * log10(b) + m0;
     598          }
     599          else {
     600            copy->data.F32[y][x] = image->data.F32[y][x];
     601          }
     602        }
     603      }
     604      break;
     605    case PS_TYPE_F64:
     606        for (int y = 0; y < numRows; y++) {
     607          for (int x = 0; x < numCols; x++) {
     608            //      fprintf(stderr,"psFS64: %d %d %g %g %g\n",x,y,offset,image->data.F64[y][x],log10(image->data.F64[y][x] - offset));
     609            if (isfinite(image->data.F64[y][x])) {
     610              copy->data.F64[y][x] = a * asinh( (image->data.F64[y][x] - *boffset) / (2 * *bsoften));// - 2.5 * log10(b) + m0;
     611            }
     612            else {
     613              copy->data.F64[y][x] = image->data.F64[y][x];
     614            }     
     615          }
     616        }
     617      break;
     618    default:
     619      psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Target type is not a float: %d",image->type.type);
     620      return NULL;
     621      break;
     622    }
     623     
     624    // Do regular scaling on the logarithm image
     625    if (!scaleStdev(bscale, bzero, copy, mask, maskVal, options)) {
     626      psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
     627      return false;
     628    }
     629    psFree(copy);
     630    return true;
     631}
     632
     633static bool asinhRange(double *bscale, // Scaling, to return
     634                       double *bzero,  // Zero point, to return
     635                       double *boffset, // asinh flux zeropoint, to return
     636                       double *bsoften, // asinh softening parameter, to return
     637                       const psImage *image, // Image to scale
     638                       const psImage *mask,  // Mask image
     639                       psImageMaskType maskVal, // value to mask
     640                       const psFitsOptions *options // FITS options
     641                       )
     642{
     643  psAssert(bscale, "impossible");
     644  psAssert(bzero, "impossible");
     645  psAssert(bsoften, "impossible");
     646  psAssert(image, "impossible");
     647  psAssert(options, "impossible");
     648
     649  psTrace("psLib.fits", 3, "Scaling image by asinh method");
     650  int numCols = image->numCols, numRows = image->numRows; // Size of image
     651 
     652    // Measure the mean and stdev
     653    // psImageBackground automatically excludes pixels that are non-finite, so we don't need to bother about a
     654    // mask.
     655    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);
     656    psStats *stats = psStatsAlloc(MEAN_STAT | STDEV_STAT); // Statistics object
     657    double mean, stdev;                                    // Mean and standard deviation
     658    if (!psImageBackground(stats, NULL, image, mask, maskVal, rng)) {
     659        // It could be because the image is entirely masked, in which case we don't want to error
     660        bool good = false;              // Any good pixels?
     661
     662
     663// Find good pixels in an image, by image type
     664#define GOOD_PIXELS_CASE(TYPE) \
     665      case PS_TYPE_##TYPE: \
     666        for (int y = 0; y < image->numRows && !good; y++) { \
     667            for (int x = 0; x < image->numCols && !good; x++) { \
     668                if (mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) { \
     669                    continue; \
     670                } \
     671                if (!isfinite(image->data.TYPE[y][x])) { \
     672                    continue; \
     673                } \
     674                good = true; \
     675            } \
     676        } \
     677        break;
     678
     679        switch (image->type.type) {
     680            GOOD_PIXELS_CASE(F32);
     681            GOOD_PIXELS_CASE(F64);
     682          default:
     683            psAbort("Unsupported case: %x", image->type.type);
     684        }
     685
     686        if (!good) {
     687            psLogMsg("psLib.fits", PS_LOG_DETAIL, "Image has no good pixels, setting BSCALE = 1, BZERO = 0");
     688            psErrorClear();
     689            *bscale = 1.0;
     690            *bzero = 0.0;
     691            *bsoften = NAN;
     692            psFree(rng);
     693            psFree(stats);
     694            return true;
     695        }
     696
     697        // There are some good pixels in there somewhere; psImageBackground just didn't find them
     698        psLogMsg("psLib.fits", PS_LOG_DETAIL,
     699                 "Couldn't measure background statistics for image quantisation; retrying.");
     700        psErrorClear();
     701        // Retry using all the available pixels
     702        stats->nSubsample = image->numCols * image->numRows + 1;
     703        if (!psImageStats(stats, image, mask, maskVal)) {
     704            psLogMsg("psLib.fits", PS_LOG_DETAIL,
     705                     "Couldn't measure background statistics for image quantisation (attempt 2); retrying.");
     706            psErrorClear();
     707            // Retry with desperate statistic
     708            stats->options = DESPERATE_MEAN_STAT | DESPERATE_STDEV_STAT;
     709            if (!psImageStats(stats, image, mask, maskVal)) {
     710                psError(PS_ERR_UNKNOWN, false, "Unable to measure background statistics for image");
     711                psFree(rng);
     712                psFree(stats);
     713                return false;
     714            } else {
     715                // Desperate retry
     716                mean = psStatsGetValue(stats, DESPERATE_MEAN_STAT);
     717                stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
     718            }
     719        } else {
     720            // Retry with all available pixels
     721            mean = psStatsGetValue(stats, MEAN_STAT);
     722            stdev = psStatsGetValue(stats, STDEV_STAT);
     723        }
     724    } else {
     725        // First attempt
     726        mean = psStatsGetValue(stats, MEAN_STAT);
     727        stdev = psStatsGetValue(stats, STDEV_STAT);
     728    }
     729    psFree(rng);
     730    psFree(stats);
     731    if (!isfinite(mean) || !isfinite(stdev)) {
     732        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     733                "Mean (%f) or stdev (%f) is non-finite.", mean, stdev);
     734        return false;
     735    }
     736
     737    psImage *copy;
     738
     739    switch (image->type.type) {
     740    case PS_TYPE_F32:
     741      copy = psImageCopy(NULL,image,PS_TYPE_F32);
     742      break;
     743    case PS_TYPE_F64:
     744      copy = psImageCopy(NULL,image,PS_TYPE_F64);
     745      break;
     746    default:
     747      psError(PS_ERR_UNKNOWN, true, "Target type is not a float: %d", image->type.type);
     748      return NULL;
     749      break;
     750    }
     751    // Do scaling
     752    float a = 1.0857362; // 2.5 * log(e);
     753    *bsoften = sqrt(a) * stdev;
     754    *boffset = mean;
     755    // float m0 = 0; // Can I just arbitrarily set this?
     756   
     757    switch (image->type.type) {
     758    case PS_TYPE_F32:
     759      for (int y = 0; y < numRows; y++) {
     760        for (int x = 0; x < numCols; x++) {
     761/*        if (x == 2331 && y == 2843) { */
     762/*          fprintf(stderr,"psFS32: %d %d %g %g %g\n",x,y,offset,image->data.F32[y][x],log10(image->data.F32[y][x] - offset)); */
     763/*        } */
     764/*        if (x == 266 && y == 4584) { */
     765/*          fprintf(stderr,"psFS32: %d %d %g %g %g %g %g\n",x,y,*boffset,*bsoften,image->data.F32[y][x],log10(image->data.F32[y][x] - *boffset), */
     766/*                  a * asinh((image->data.F32[y][x] - *boffset) / (2 * *bsoften))); */
     767/*        } */
     768
     769          if (isfinite(image->data.F32[y][x])) {
     770            copy->data.F32[y][x] = a * asinh( (image->data.F32[y][x] - *boffset) / (2 * *bsoften));// - 2.5 * log10(b) + m0;
     771          }
     772          else {
     773            copy->data.F32[y][x] = image->data.F32[y][x];
     774          }
     775        }
     776      }
     777      break;
     778    case PS_TYPE_F64:
     779        for (int y = 0; y < numRows; y++) {
     780          for (int x = 0; x < numCols; x++) {
     781            //      fprintf(stderr,"psFS64: %d %d %g %g %g\n",x,y,offset,image->data.F64[y][x],log10(image->data.F64[y][x] - offset));
     782            if (isfinite(image->data.F64[y][x])) {
     783              copy->data.F64[y][x] = a * asinh( (image->data.F64[y][x] - *boffset)/ (2 * *bsoften));// - 2.5 * log10(b) + m0;
     784            }
     785            else {
     786              copy->data.F64[y][x] = image->data.F32[y][x];
     787            }
     788          }
     789        }
     790      break;
     791    default:
     792      psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Target type is not a float: %d",image->type.type);
     793      return NULL;
     794      break;
     795    }
     796     
     797    // Do regular scaling on the asinh image
     798    if (!scaleRange(bscale, bzero, copy, options)) {
     799      psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
     800      return false;
     801    }
     802    psFree(copy);
     803    return true;
     804}
     805
    458806
    459807//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    461809//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    462810
    463 bool psFitsScaleDetermine(double *bscale, double *bzero, double *boffset, long *blank, const psImage *image,
     811bool psFitsScaleDetermine(double *bscale, double *bzero, double *boffset, double *bsoften,
     812                          long *blank, const psImage *image,
    464813                          const psImage *mask, psImageMaskType maskVal, const psFits *fits)
    465814{
     
    521870        }
    522871        break;
    523     case PS_FITS_SCALE_LOG_RANGE:
    524       if (!logscaleRange(bscale,bzero,boffset,image,options)) {
    525         psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from range");
    526         return false;
    527       }
    528       break;
    529     case PS_FITS_SCALE_LOG_STDEV_POSITIVE:
    530     case PS_FITS_SCALE_LOG_STDEV_NEGATIVE:
    531     case PS_FITS_SCALE_LOG_STDEV_BOTH:
    532       if (!logscaleStdev(bscale, bzero,boffset, image, mask, maskVal, options)) {
    533             psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
    534             return false;
    535         }
    536         break;
     872      case PS_FITS_SCALE_LOG_RANGE:
     873        if (!logscaleRange(bscale,bzero,boffset,image,options)) {
     874          psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from range");
     875          return false;
     876        }
     877        break;
     878      case PS_FITS_SCALE_LOG_STDEV_POSITIVE:
     879      case PS_FITS_SCALE_LOG_STDEV_NEGATIVE:
     880      case PS_FITS_SCALE_LOG_STDEV_BOTH:
     881        if (!logscaleStdev(bscale, bzero,boffset, image, mask, maskVal, options)) {
     882          psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
     883          return false;
     884        }
     885        break;
     886      case PS_FITS_SCALE_ASINH_RANGE:
     887        if (!asinhRange(bscale,bzero,boffset,bsoften,image,mask,maskVal,options)) {
     888          psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from range");
     889          return false;
     890        }
     891        break;
     892      case PS_FITS_SCALE_ASINH_STDEV_POSITIVE:
     893      case PS_FITS_SCALE_ASINH_STDEV_NEGATIVE:
     894      case PS_FITS_SCALE_ASINH_STDEV_BOTH:
     895        if (!asinhStdev(bscale, bzero,boffset,bsoften, image, mask, maskVal, options)) {
     896          psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
     897          return false;
     898        }
     899        break;
     900       
     901       
    537902      case PS_FITS_SCALE_MANUAL:
    538903        *bscale = options->bscale;
     
    557922
    558923
    559     psTrace("psLib.fits", 3, "BSCALE = %.10lf, BZERO = %.10lf, BOFFSET = %.10lf, BLANK = %ld\n",
    560             *bscale, *bzero, *boffset, *blank);
     924    psTrace("psLib.fits", 3, "BSCALE = %.10lf, BZERO = %.10lf, BOFFSET = %.10lf, BSOFTEN = %.10lf, BLANK = %ld\n",
     925            *bscale, *bzero, *boffset, *bsoften, *blank);
    561926    return true;
    562927}
    563928
    564929
    565 psImage *psFitsScaleForDisk(const psImage *image, const psFits *fits, double bscale, double bzero, double boffset,
     930psImage *psFitsScaleForDisk(const psImage *image, const psFits *fits, double bscale, double bzero, double boffset, double bsoften,
    566931                            psRandom *rng)
    567932{
     
    625990                  (options->scaling == PS_FITS_SCALE_LOG_STDEV_NEGATIVE)|| \
    626991                  (options->scaling == PS_FITS_SCALE_LOG_STDEV_BOTH)) { \
    627                 value = log10( (IN)->data.INTYPE[y][x] - boffset ); \
     992                if (isfinite((IN)->data.INTYPE[y][x])) {                \
     993                  value = log10( (IN)->data.INTYPE[y][x] - boffset );   \
     994                }                                                       \
     995                else {                                                  \
     996                  value = (IN)->data.INTYPE[y][x];                      \
     997                }                                                       \
     998              }                                                         \
     999              else if ((options->scaling == PS_FITS_SCALE_ASINH_RANGE)||        \
     1000                (options->scaling == PS_FITS_SCALE_ASINH_MANUAL)||        \
     1001                  (options->scaling == PS_FITS_SCALE_ASINH_STDEV_POSITIVE)|| \
     1002                  (options->scaling == PS_FITS_SCALE_ASINH_STDEV_NEGATIVE)|| \
     1003                  (options->scaling == PS_FITS_SCALE_ASINH_STDEV_BOTH)) {       \
     1004                if (isfinite((IN)->data.INTYPE[y][x])) {                \
     1005                  value = 1.0857362 * (asinh( ((IN)->data.INTYPE[y][x] - boffset) / (2.0 * bsoften))); \
     1006                }                                                       \
     1007                else {                                                  \
     1008                  value = (IN)->data.INTYPE[y][x];                      \
     1009                }                                                       \
     1010                if ((x == 1000)&&(y == 1000)) {                         \
     1011                  fprintf(stderr,"ASINH: %f %f %f",                     \
     1012                          (IN)->data.INTYPE[y][x],value,bsoften);       \
     1013                }                                                       \
    6281014              }                                                         \
    6291015                else { \
     
    6521038    case PS_TYPE_##INTYPE: { \
    6531039        switch (outType) { \
    654             SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, U8); \
    655             SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S16); \
    656             SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S32); \
    657             SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S64); \
     1040          SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, U8);;   \
     1041          SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S16);;  \
     1042          SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S32);;  \
     1043          SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S64);;  \
    6581044          default: \
    6591045            psAbort("Should be unreachable."); \
     
    6641050    switch (image->type.type) {
    6651051        SCALE_WRITE_IN_CASE(image, F32, out);
    666         SCALE_WRITE_IN_CASE(image, F64, out);
     1052        SCALE_WRITE_IN_CASE(image, F64, out); 
    6671053      default:
    6681054        psAbort("Should be unreachable.");
     
    6791065// the present time, since cfitsio should apply the scaling itself in the process of reading.  However, we may
    6801066// later desire it (e.g., if we ever make our own FITS implementation).
    681 psImage *psFitsScaleFromDisk(const psImage *image, double boffset)
     1067psImage *psFitsScaleFromDisk(const psImage *image, double boffset, double bsoften)
    6821068{
    6831069    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
     
    7181104      for (int y = 0; y < numRows; y++) { \
    7191105          for (int x = 0; x < numCols; x++) { \
    720             out->data.OUTTYPE[y][x] = pow(10,image->data.INTYPE[y][x]) + boffset;; \
     1106            if (bsoften) {                                              \
     1107              out->data.OUTTYPE[y][x] = 2 * bsoften * sinh(image->data.INTYPE[y][x] / (1.0857362)) + boffset; \
     1108            }                                                           \
     1109            else if (boffset) {                                 \
     1110              out->data.OUTTYPE[y][x] = pow(10,image->data.INTYPE[y][x]) + boffset;; \
     1111             }                                                                  \
    7211112          } \
    7221113      } \
     
    7661157    if (strcasecmp(string, "LOG_STDEV_NEGATIVE") == 0) return PS_FITS_SCALE_LOG_STDEV_NEGATIVE;
    7671158    if (strcasecmp(string, "LOG_STDEV_BOTH") == 0) return PS_FITS_SCALE_LOG_STDEV_BOTH;
     1159    if (strcasecmp(string, "ASINH_RANGE") == 0)      return PS_FITS_SCALE_ASINH_RANGE;
     1160    if (strcasecmp(string, "ASINH_MANUAL") == 0)      return PS_FITS_SCALE_ASINH_MANUAL;
     1161    if (strcasecmp(string, "ASINH_STDEV_POSITIVE") == 0) return PS_FITS_SCALE_ASINH_STDEV_POSITIVE;
     1162    if (strcasecmp(string, "ASINH_STDEV_NEGATIVE") == 0) return PS_FITS_SCALE_ASINH_STDEV_NEGATIVE;
     1163    if (strcasecmp(string, "ASINH_STDEV_BOTH") == 0) return PS_FITS_SCALE_ASINH_STDEV_BOTH;
    7681164    if (strcasecmp(string, "MANUAL") == 0)         return PS_FITS_SCALE_MANUAL;
    7691165
  • branches/eam_branches/ipp-20110505/psLib/src/fits/psFitsScale.h

    r30636 r31656  
    1111                          double *bzero, ///< Zero point, to return
    1212                          double *boffset, ///< Log offset, to return
     13                          double *bsoften, ///< asinh softening parameter, to return
    1314                          long *blank,  ///< Blank value, to return
    1415                          const psImage *image, ///< Image to scale
     
    2930                            double bzero, ///< Zero point
    3031                            double boffset, ///< Log offset
     32                            double bsoften, ///< asinh softening parameter
    3133                            psRandom *rng ///< Random number generator (for the "fuzz"), or NULL
    3234    );
    3335psImage *psFitsScaleFromDisk(const psImage *image, ///< Image to to unapply BOFFSET
    34                              double boffset        ///< Log offset
     36                             double boffset,        ///< Log offset
     37                             double bsoften         ///< asinh softening parameter
    3538                             );
    3639/// Interpret a string as a scaling method
Note: See TracChangeset for help on using the changeset viewer.