#524 NCDF_VARGET fails for string array

v1.0 (example)
closed-accepted
nobody
None
5
2013-08-30
2013-03-25
Harald Anlauf
No

Hello,

the attached example shows that gdl-0.9.3 fails for me when reading a string array from a NetCDF file.
Expected output (from IDL):
Open NetCDF file: test.nc

Global attribute: Experiment = 9029
Dimensions: 2
Inquire Dimension 0 : n_rep= 3
Inquire Dimension 1 : len8= 8

Reading dates:
varid : 0
long_name : date
units : yyyymmdd
varinq : { date LONG 1 2 0
}
ndims : 1
dates : 20121031 20121031 20121031

Reading station names:
varid : 3
long_name : station id in character form
varinq : { statid CHAR 2 1 1 0
}
ndims : 2
station_id: CO022338 CO062338 CO022254

However, with gdl the read of array station_id fails:

% NCDF_VARGET: (NC_ERROR=-56)
% Execution halted at: GDLTEST 48 gdltest.pro
% $MAIN$

Is there a workaround?

Discussion

  • Harald Anlauf
    Harald Anlauf
    2013-03-25

    Demo gdl source file

     
    Attachments
  • Harald Anlauf
    Harald Anlauf
    2013-03-25

    The NetCDF file used in the test

     
    Attachments
  • Alain C.
    Alain C.
    2013-03-26

    Thank you for reporting and giving a concrete example !
    This bug was reported before but I was not able to create a test case !

    We will try to find a solution ASAP

    Alain

     
  • Martin Svec
    Martin Svec
    2013-06-25

    Alain, if you are interested, I can provide another concrete example of this.

     
  • Alain C.
    Alain C.
    2013-08-17

    sorry for the delay, too busy

    I made some tests in the code, and found 3 intricated problems:
    -- one problem in the block line 485 in "ncdf_var_cl.cpp"
    if (var_type == NC_CHAR ) ...
    -- I need to deactivate the catching "ncdf_var_handle_error" (-56)
    in this case (we have to change that for that specific case in the future)
    -- last trouble : when I did that, instead or receiving the CO...
    results, I have "date" :(

    no time to work on that issue before next week, any advice/help/patch welcome !

    Alain

     
    • Harald Anlauf
      Harald Anlauf
      2013-08-26

      Alain,

      error (-56) is (according to netcdf.h):

      #define NC_ECHAR        (-56)   /* Attempt to convert between text & numbers */
      

      which, according to the NetCDF website, means:

      NC_ECHAR Attempt to convert to or from char.

      I will try to create a simple C testcase to investigate this further.

       
  • Harald Anlauf
    Harald Anlauf
    2013-08-27

    I am not so familiar with NetCDF's C interface than with the Fortran version,
    but here's what I found out:

    nc_inq_vartype returns vartype = 2 = NC_CHAR, which I can only read using
    nc_get_var_text. Trying to use nc_get_var_{s,u}char results in the error:

    NetCDF: Attempt to convert between text & numbers

    which is what we already know. The solution appears obvious, but
    I do not know how to implement it properly. I tried the following:

    diff -up src/ncdf_var_cl.cpp~ src/ncdf_var_cl.cpp
    --- src/ncdf_var_cl.cpp~        2012-12-27 17:22:44.000000000 +0100
    +++ src/ncdf_var_cl.cpp 2013-08-27 22:40:35.000000000 +0200
    @@ -496,7 +496,7 @@ else if(var_type == NC_LONG)
           else if (var_type == NC_CHAR)
           {
             DByteGDL* temp = new DByteGDL(dim, BaseGDL::NOZERO);
    -        status = nc_get_var_uchar(cdfid, varid, &(*temp)[0]);
    +        status = nc_get_var_text(cdfid, varid, &(*temp)[0]);
             ncdf_var_handle_error(e, status, "NCDF_VARGET", temp);
             GDLDelete(e->GetParGlobal(2));
             e->GetParGlobal(2) = temp;
    @@ -618,7 +618,7 @@ else if(var_type == NC_LONG)
             else if (var_type == NC_CHAR)
             {
               DByteGDL *temp = new DByteGDL(dim, BaseGDL::NOZERO);
    -          status = nc_get_vara_uchar(cdfid, varid, off, cou, &(*temp)[0]);
    +          status = nc_get_vara_text(cdfid, varid, off, cou, &(*temp)[0]);
               ncdf_var_handle_error(e, status, "NCDF_VARGET", temp);
               GDLDelete(e->GetParGlobal(2));
               e->GetParGlobal(2) = temp;
    @@ -734,7 +734,7 @@ else if(var_type == NC_LONG)
             else if (var_type == NC_CHAR)
             {
               DByteGDL *temp = new DByteGDL(dim, BaseGDL::NOZERO);
    -          status = nc_get_vars_uchar(cdfid, varid, off, cou, stri, &(*temp)[0]);
    +          status = nc_get_vars_text(cdfid, varid, off, cou, stri, &(*temp)[0]);
               ncdf_var_handle_error(e, status, "NCDF_VARGET", temp);
               GDLDelete(e->GetParGlobal(2));
               e->GetParGlobal(2) = temp;
    

    but the compile fails with:

    ncdf_var_cl.cpp: In function 'void lib::ncdf_varget(EnvT)':
    ncdf_var_cl.cpp:499:59: error: invalid conversion from 'Data_<SpDByte>::Ty
    {aka unsigned char}' to 'char' [-fpermissive]
    /usr/include/netcdf.h:809:1: error: initializing argument 3 of 'int nc_get_var_text(int, int, char)' [-fpermissive]
    ncdf_var_cl.cpp:621:72: error: invalid conversion from 'Data_<SpDByte>::Ty
    {aka unsigned char}' to 'char' [-fpermissive]
    /usr/include/netcdf.h:542:1: error: initializing argument 5 of 'int nc_get_vara_text(int, int, const size_t, const size_t, char)' [-fpermissive]
    ncdf_var_cl.cpp:737:78: error: invalid conversion from 'Data_<SpDByte>::Ty
    {aka unsigned char}' to 'char' [-fpermissive]
    /usr/include/netcdf.h:620:1: error: initializing argument 6 of 'int nc_get_vars_text(int, int, const size_t, const size_t, const ptrdiff_t, char)' [-fpermissive]

     
  • Alain C.
    Alain C.
    2013-08-27

    I also try such changes and variations, without success up to now :(

    Alain

     
  • Harald Anlauf
    Harald Anlauf
    2013-08-28

    OK, I added a cast of the pointer to the receiving buffer, so that the function prototype gets accepted. I don't know whether there is a better way to achieve this, but it works for me. The testsuite shows no additional failures, and my own example now passes. It prints the expected

    station_id: CO022338 CO062338 CO022254

    Latest version of the patch attached.

    Harald

     
  • Alain C.
    Alain C.
    2013-08-30

    Great ! solved !! I updated the CVS. Thanks !!

    If time, I will revisited the NetCDF in the testsuite/

    Alain

     
  • Alain C.
    Alain C.
    2013-08-30

    • status: open --> closed-accepted
    • Group: --> v1.0 (example)