Skip to content

Assigning new data to an existing HDU won't update scaling consistently #5559

@rcardenes

Description

@rcardenes

When creating a brand new ImageHDU, this:

im = ImageHDU(data=data, header=existing_header)

will deal properly with the header scaling, adding or subtracting BZERO/BSCALE to fit the data type, no matter what the data type is, or whether the original header has scaling information on it or not. If we set the data after creation, the behavior is not consistent. Let's show this.

>>> uint8 = np.array([[1,2,3,4],[4,3,2,1]], dtype='uint8')
>>> uint64 = np.array([[1,2,3,4],[4,3,2,1]], dtype='uint64')

Now, let's create a new image with a data type that doesn't require scaling, and replace the data with the unsigned 64 bit array:

>>> im = ImageHDU(uint8)
>>> im.header
XTENSION= 'IMAGE   '           / Image extension                                
BITPIX  =                   8 / array data type                                
NAXIS   =                    2 / number of array dimensions                     
NAXIS1  =                    4                                                  
NAXIS2  =                    2                                                  
PCOUNT  =                    0 / number of parameters                           
GCOUNT  =                    1 / number of groups                               
>>> im.data = uint64
>>> im.header
XTENSION= 'IMAGE   '           / Image extension                                
BITPIX  =                   64 / array data type                                
NAXIS   =                    2 / number of array dimensions                     
NAXIS1  =                    4                                                  
NAXIS2  =                    2                                                  
PCOUNT  =                    0 / number of parameters                           
GCOUNT  =                    1 / number of groups                               
BSCALE  =                    1                                                  
BZERO   =  9223372036854775808                                                  

It behaves as expected. Now:

>>> im = ImageHDU(uint64)
>>> im.header
XTENSION= 'IMAGE   '           / Image extension                             
BITPIX  =                   64 / array data type                                
NAXIS   =                    2 / number of array dimensions                  
NAXIS1  =                    4                                               
NAXIS2  =                    2                                               
PCOUNT  =                    0 / number of parameters                        
GCOUNT  =                    1 / number of groups                            
BSCALE  =                    1                                               
BZERO   =  9223372036854775808                                               
>>> im.data = uint8
>>> im.header
XTENSION= 'IMAGE   '           / Image extension                             
BITPIX  =                    8 / array data type                                
NAXIS   =                    2 / number of array dimensions                  
NAXIS1  =                    4                                               
NAXIS2  =                    2                                               
PCOUNT  =                    0 / number of parameters                        
GCOUNT  =                    1 / number of groups                            
BSCALE  =                    1                                               
BZERO   =  9223372036854775808                                               

As we can see, scaling info is preserved, when it shouldn't. This works properly if the new array is of 16/32/64 integer (signed or unsigned), but fails with 8 bit and floating point data.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions