[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[netCDF #UGH-617347]: Trouble reading a 4D NetCDF variable with c++ interface



Hi Michèle,

Sorry to have taken so long to respond to your question.

> I am hoping you can help me with the following problem:
> 
> I need to read a NetCDF file whose cdl version is attached to this email
> (data.cdl). The data.nc file is 1.88 GB of size. I am using the c++
> interface. I successfully extracted the 1D variables "x", "y", "z", and
> "time", but the extraction of the 4D variables (e.g. "QN") fails.
> 
> For instance, suppose I want to extract the "QN" variable, which is a 14 x
> 2048 x 2048 z-y-x grid, with 1 timestep (record) of data. The code
> compiles (I am using the Intel C++ Compiler, version 11.0 I believe) and
> runs fine, but the resulting "qnIn" array has (1) the wrong dimensions,
> and (2) ill positioned data.
> 
> I have attached the c++ code (test.cpp) that I wrote for the extraction.
> Please let me know if you need any other information in order to diagnose
> the problem. I really appreciate your assistance, and look forward to your
> response.

I think the problem is with the statement

  if (!qn -> get(&qnIn[0][0][0],1,ZDIM,YDIM,XDIM)) return NC_ERR;

where you are trying to read all the data into the qnIn array.  But
that array is not a set of contiguous values in memory, because it
was allocated one row at a time:

  /* Allocate dynamically the qnIn array */ 
  qnIn = new float**[ZDIM];
  for (int j = 0; j < ZDIM; ++j)
  {
     qnIn[j] = new float*[YDIM];
     for (int k = 0; k < YDIM; ++k)
        qnIn[j][k] = new float[XDIM];
  }

Therefore, the value qnIn[j+1][k] does not necessarily follow
the value qnIn[j][YDIM-1] in memory, but may be allocated in a
different part of memory.  You could check this by printing the
addesses of the rows of the array, and note that there will be
one or more gaps indicating that the array has been allocated 
memory in non-contiguous blocks.

It's a requirement of netCDF that arrays used as arguments to netCDF
calls, except for the C nc_get_varm() and nc_put_varm() calls, are
contiguous blocks of memory.  I just checked the C++ documentation and
noted it doesn't make that clear, but it's definitely in the
language-neutral netCDF Users guide, for example:

  An array section is a "slab" or contiguous rectangular block that is
  specified by two vectors. The index vector gives the indices of the
  element in the corner closest to the origin. The count vector gives
  the lengths of the edges of the slab along each of the variable's
  dimensions, in order. The number of values accessed is the product
  of these edge lengths.

We've recently had another question indicating we need to make this
clearer in the documentation, and I will see that that is done before
the next release.  You can follow the progress of this fix in our bugs
database, here:

  https://www.unidata.ucar.edu/jira/browse/NCF-69

Thanks for pointing out the documentation problem!

--Russ

Russ Rew                                         UCAR Unidata Program
address@hidden                      http://www.unidata.ucar.edu



Ticket Details
===================
Ticket ID: UGH-617347
Department: Support netCDF
Priority: Critical
Status: Closed