NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.

To learn about what's going on, see About the Archive Site.

Packing data: scale_factor add_offset

The idea is that you store the most signifant bits of the original REAL
value in a INTEGER*2. The way you do this is to make those bits the integer
part of a real number, then trucate by storing into an integer. EG:

1. If you want to store the top 4 digits of .12345 :

  10000 * .12345 = 1234.5

truncate and store in the netcdf file: 1234

then the reading program has to know to divide by the scale:

  1234 / 100000 = .1234

which is a close approximation to the original number .12345


2. What should the scale and offset be? Normally you store a group of
numbers, all with the same scale and offset. So first you calculate the min
and max of that group of numbers. Also let max_integer = maximum integer (eg
for INTEGER*2 this equals 32,167).

then
     offset = min
     scale = max_integer / (max - min)

store this number into netcdf file:

     store_x = (x - offset) * scale = max_integer * (x - min) / (max - min)

note that when x = min, store_x = 0, and when x = max, store_x
max_integer.

the reading program should use the formula

    x = store_x/scale + offset.

In your example below, I suspect that the scale may be incorrect, but the
actual formula is ok.



----- Original Message -----
Sent: Monday, May 13, 2002 3:13 AM


> Hi
>
> I'm a relatively new netCDF user.  Having read the netCDF guide plus
> some entries in the support and user forum, I have a burning question
> regarding data packing using 'scale_factor' and 'add_offset'.  I've seen
> fortran code which implement the packing with code like the following
> sample snippet:
>
> INTEGER*2 X_PACKED
> REAL X, OFFSET, SCALE
>
> X = 10.23456
> OFFSET = 9.0
> SCALE = 0.23123
>
> X_PACKED = (X-OFFSET)*SCALE
> ! Then proceed to store X_PACKED in netCDF form.
> . . .
>
> What I don't understand is how this can be "correct".  When you assign a
> REAL to an INTEGER, the value of the REAL gets truncated before being
> stored in the INTEGER.  Thus, the original value of X cannot be
> 'reconstructed' from the corresponding INTEGER*2 variable (X_PACKED) in
> the netCDF file.
>
> I understand the intent is to store only the 2 bytes that represents the
> scaled-down REAL value.  But as far as I know, this is not possible in
> Fortran -- as far as simply assigning values to variables is concerned.
>
> Or is the above fortran implementation of packing in netCDF completely
> off track?  Am I missing anything?
> What is the common practice of netCDF packing in Fortran?
> Any sample Fortran code for netCDF data packing?
>
> Thanks for any explanations or tips.
>
> -Kek
> Tropical Marine Sc Institute
> Singapore
>


  • 2002 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: