Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#31 bzero scaled wrong in wfits

critical
closed-fixed
nobody
other (94)
5
2002-04-05
2002-03-18
Anonymous
No

I think the logic which set the value of bzero in wfits
is incorrect.

The bscale should be set to the minimum of the allowed
datavalues or the actual datavalues , which ever is
least. This preserves the most dynamic range. Here's
the diff that should impove things.

IO/Misc/misc.pd

392c392
< $bzero = $dmin < $min ? $dmin : $min ;
---
> $bzero = $min;

JJ Kavelaars
DPA
McMaster University.

Discussion

  • Logged In: NO

    That line should be

    $bzero = $dmin < $min ? -1*$dmin : -1*$min

    (the bzero is added to the values to scale).

    JJ

     
  • JJ Kavelaars
    JJ Kavelaars
    2002-03-18

    Logged In: YES
    user_id=408846

    That line should be

    $bzero = $dmin < $min ? -1*$dmin : -1*$min

    (the bzero is added to the values to scale).

    JJ

     
  • Logged In: YES
    user_id=1796

    Errrmmmm

    the wfits() code currently looks like this according to
    CVS:

    my $min = $pdl->min;
    my $max = $pdl->max;
    my ($dmin,$dmax) = (0, 2**8-1) if $BITPIX == 8;
    ($dmin,$dmax) = (-2**15, 2**15-1) if $BITPIX == 16;
    ($dmin,$dmax) = (-2**31, 2**31-1) if $BITPIX == 32;

    if ($min<$dmin || $max>$dmax) {
    $bzero = $min;
    $max -= $bzero;
    $bscale = $max/$dmax if $max>$dmax;
    }

    i.e. if the data is within the represented range, no bzero
    is applied, otherwise $min is
    used as you suggest

    This already seems correct to me

    Karl

     
  • JJ Kavelaars
    JJ Kavelaars
    2002-03-18

    Logged In: YES
    user_id=408846

    If you use the current wfits to write a file that has data
    in the ushort range of
    0-65500 then wfits will SCALE that using a BSCALE=2 and
    BZERO=0. This is not the correct behavoiur.

    The conditional expression for the choosing $bzero/$bscale
    is an OR so it catches the case when $min>$dmin &&
    $max>$dmax ...

    but the rule for $bzero assumes that $min is less than $dmin
    which isn't always true. As the example I outlined above
    shows the current logic results in $bscale=2 which costs you
    dynamic range.

    $bzero = $min<$dmin ? $min : $dmin ; # This provides the
    fullest possible DR

    I was tired last night when I suggested that a -1 is needed.
    :-) Sorry.

    JJ

     
  • JJ Kavelaars
    JJ Kavelaars
    2002-03-18

    Logged In: YES
    user_id=408846

    OK OK... I'm still wrong... more testing and coffee
    indicates that.

    $bzero = $min - $dmin ; # appears to gives the desired
    behaviour.

    ## This sets bzero to the smallest possible value that keeps
    the data insidethe
    ## allowed fits datatype range.
    ## Sheesh. Sorry of the confusion.

     
  • Logged In: YES
    user_id=1796

    I still don't understand, your remark about wfits is wrong.
    e.g.

    perldl> $x = ushort random(100,100)*10+20
    perldl> stats $x
    Mean = 24.4924, RMS = 2.8781143549206, Median = 25
    Min = 20, Max = 29

    perldl>
    perldl> wfits $x,'foo.fits'
    BSCALE = 1 && BZERO = 0

    So data within the ushort range is written correctly I think

    Please let us take the discussion to email - I am
    kgb@pha.jhu.edu

     
  • Logged In: YES
    user_id=1796

    After discussion proposed patch fixed and tested and
    committed to
    CVS - kgb

     
    • status: open --> closed-fixed