Due to the current gap in continued funding from the U.S. National Science Foundation (NSF), the NSF Unidata Program Center has temporarily paused most operations. See NSF Unidata Pause in Most Operations for details.

[netcdfgroup] Odd failure reading compressed 32-bit floats with nc_get_var_double()?

  • To: netcdfgroup@xxxxxxxxxxxxxxxx
  • Subject: [netcdfgroup] Odd failure reading compressed 32-bit floats with nc_get_var_double()?
  • From: David Pierce <dpierce@xxxxxxxx>
  • Date: Tue, 8 Sep 2020 15:30:52 -0700
  • Pp_allow_relay: proofpoint_allowed
Hello netcdf-ers,

I had a user of the R ncdf4 package alert me to an odd and perplexing
apparent bug in the netcdf library. It is triggered by the netcdf file you
can download here:

http://cirrus.ucsd.edu/~pierce/tmp/mendota_buoy.2018-11-08.nc

This file has the following variable (among others):

float phycocyanin(time) ;
            phycocyanin:_FillValue = -9999.f ;
            phycocyanin:units = "RFU" ;
            phycocyanin:long_name = "Phycocyanin" ;
            phycocyanin:_Storage = "chunked" ;
            phycocyanin:_ChunkSizes = 1440 ;
            phycocyanin:_DeflateLevel = 4 ;
            phycocyanin:_Shuffle = "true" ;
            phycocyanin:_Endianness = "little" ;

'ncdump' reports all the data as missing:

phycocyanin = _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
(etc.)

When I read the data into a floating point array using the C library using
nc_get_var_float() then I get the expected values of -9999.0. However when
I read it into a double precision array with nc_get_var_double() then I get
strange values. Here is the output of the little test program that I've
appended below:

Sizeof float: 4 double: 8
======== DOUBLE ========
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
-559239646634519513659653226496.000000
======== FLOAT ========
-9999.000000 -9999.000000 -9999.000000 -9999.000000 -9999.000000
-9999.000000 -9999.000000 -9999.000000 -9999.000000 -9999.000000

This seems like a bug, unless I'm overlooking something obvious in the test
code (always possible). The nc_get_var_double() call is supposed to convert
the netcdf file's values into double precision and store them in the
provided double precision array, right? That's my understanding anyway. I
can't see why they are not -9999.00's in the resultant array.

Any thoughts are appreciated,

--Dave

Test program:

#include <stdio.h>
#include <stdlib.h>
#include "netcdf.h"

void main( int argc, char *argv[] )
{
        int     err, ncid, varid;
        size_t  nt;
        double  *ddat;
        float   *fdat;

        nt = 1440;      /* just hardcode for test */

        printf( "Sizeof float: %ld  double: %ld\n", sizeof(float),
sizeof(double) );

        err = nc_open("mendota_buoy.2018-11-08.nc", 0, &ncid );
        if( err != 0 ) {
                printf( "err open = %d\n", err );
                exit(-1);
                }

        err = nc_inq_varid( ncid, "phycocyanin", &varid );
        if( err != 0 ) {
                printf( "err inq_varid = %d\n", err );
                exit(-1);
                }

        /* Make room for both double and floating dat */
        ddat = (double *)malloc( sizeof(double) * nt );
        fdat = (float  *)malloc( sizeof(float ) * nt );

        /* Read into double array. Supposed to convert to double...? */
        err = nc_get_var_double( ncid, varid, ddat );
        if( err != 0 ) {
                printf( "err get_var_double = %d\n", err );
                exit(-1);
                }

        printf( "======== DOUBLE ========\n" );
        for( int ii=0; ii<10; ii++ )
                printf( "%lf  ", ddat[ii] );

        printf( "\n" );

        /* === Do same thing, but for float === */

        err = nc_get_var_float( ncid, varid, fdat );
        if( err != 0 ) {
                printf( "err get_var_float = %d\n", err );
                exit(-1);
                }

        printf( "======== FLOAT ========\n" );
        for( int ii=0; ii<10; ii++ )
                printf( "%f  ", fdat[ii] );

        printf( "\n" );

}


-------------------------------------------------------------------
David W. Pierce
Division of Climate, Atmospheric Science, and Physical Oceanography
Scripps Institution of Oceanography
(858) 534-8276 (voice)  /  (858) 534-8561 (fax)    dpierce@xxxxxxxx
-------------------------------------------------------------------
  • 2020 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: