[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[netCDF #ZBT-271812]: problem reading file
- Subject: [netCDF #ZBT-271812]: problem reading file
- Date: Tue, 15 Nov 2011 06:14:21 -0700
Hi Michael,
Sorry to have taken so long to answer your question.
> I am trying to read some data from a file called TS.nc using some examples I
> found (http://www.unidata.ucar.edu/software/netcdf/examples/programs/),
> however I am having some issues. The code I am using is copied below.
> Below is the result of an ncdump -v TS TS.nc command:
> fr0103en: /ptmp/arndtma/Comp_out(=0)$ ncdump -v TS TS.nc | more
> netcdf TS {
> dimensions:
> lat = 384 ;
> lon = 576 ;
> time = UNLIMITED ; // (133 currently)
> variables:
> double lat(lat) ;
> lat:long_name = "latitude" ;
> lat:units = "degrees_north" ;
> double lon(lon) ;
> lon:long_name = "longitude" ;
> lon:units = "degrees_east" ;
> double time(time) ;
> time:long_name = "time" ;
> time:units = "days since 0001-01-01 00:00:00" ;
> time:calendar = "noleap" ;
> time:bounds = "time_bnds" ;
> float TS(time, lat, lon) ;
> TS:units = "K" ;
> TS:long_name = "Surface temperature (radiative)" ;
> TS:cell_method = "time: mean" ;
>
> // global attributes:
> :Conventions = "CF-1.0" ;
> :source = "CAM" ;
> :case = "LRC01" ;
> :title = "UNSET" ;
> :logname = "" ;
> :host = "" ;
> :Version = "$Name$" ;
> :revision_Id = "$Id$" ;
> :initial_file =
> "/lustre/scratch/proj/ccsm/inputdata/atm/cam/inic/fv/cami_1980-01-01_0.47x0.63_L26_c071226.nc"
> ;
> :topography_file =
> "/lustre/scratch/proj/ccsm/inputdata/atm/cam/topo/USGS_gtopo30_0.47x0.63_remap_c061106.nc"
> ;
> :history = "Mon Oct 17 14:30:23 2011: ncrcat -v TS
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0079-12.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.c
> am2.h0.0080-01.nc /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-02.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-03.nc
> /ptmp/dennis/LRC01/atm/hist/LRC
> 01.cam2.h0.0080-04.nc /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-05.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-06.nc
> /ptmp/dennis/LRC01/atm/hist
> /LRC01.cam2.h0.0080-07.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-08.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-09.nc /ptmp/dennis/LRC01/atm/
> hist/LRC01.cam2.h0.0080-10.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-11.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0080-12.nc /ptmp/dennis/LRC01/
> atm/hist/LRC01.cam2.h0.0081-01.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0081-02.nc
> /ptmp/dennis/LRC01/atm/hist/LRC01.cam2.h0.0081-03.nc /ptmp/dennis/LR
> C01/atm/hist/LRC01.cam2.h0.0081-04.nc /ptmp/dennis/LRC01/atm/hist/
> ...
> As you can see I created this file by extracting each variable from the
> original nc files using the ncrcat command.
>
>
> The error (Segmentation fault) comes when the code tries to read in the
> actual data and therefore I am convinced I am missing something in the length
> or structure of the data itself. The nc_open work fine, the nc_inq_varid
> works fine, it is only when I try to use the nc_get_var_float that the seg
> fault occurs.
You're correct, the problem is that you're trying to read all of the TS
variable (133 * 384 * 576 values)
into an array that can only hold 6 *12 = 72 values. The call to
nc_get_var_float(ncid, varid, &data_in[0][0])))
reads all the data from the variable identified by varid into the location
you've specified, the address of
the data_in array.
If you really want to try to read all the data for TS into memory at once,
you'll have to declare data_in to
be a much larger array, e.g.
#define NT 133
float data_in[NT][NX][NY];
But you might only need one slice at a time of the TS data, for example all the
values at a specific time.
For this, you'll need to use the function nc_get_vara_float() instead of
nc_get_var_float(), and you'll need
to provide 2 more arguments specifying where the start of the slab of data is
(e.g. the 10th time would
start at indices [9][0][0] so the "start" argument would be {9, 0, 0}) and how
large the slab is on each side
(e.g the whole 384 by 576 slice for 1 time would mean an "edges" argument of
{1,384,576}).
There are other nc_get_var* functions you can use to get just one value at a
time, or various kinds of
subsets of the data from the disk into memory where your program can do
something with it, e.g.
nc_get_var1_float(), nc_get_vars_float(), etc., but I expect
nc_get_vara_float() is what you want to use.
--Russ
> Thanks in advance,
>
> Michael
>
>
> =====
> 1 #include <stdlib.h>
> 2 #include <stdio.h>
> 3 #include <netcdf.h>
> 4
> 5
> 6 /* This is the name of the data file we will read. */
> 7
> 8 #define FILE_NAME "simple_xy.nc"
> 9
> 10 /* We are reading 2D data, a 6 x 12 grid. */
> 11
> 12 #define NX 6
> 13 #define NY 12
> 14
> 15 /* Handle errors by printing an error message and exiting with a
> 16 * non-zero status. */
> 17
> 18 #define ERRCODE 2
> 19 #define ERR(e) {printf("Error: %s\n", nc_strerror(e));
> exit(ERRCODE);}
> 20
> 21 int main()
> 22
> 23 {
> 24 /* This will be the netCDF ID for the file and data variable. */
> 25 int ncid, varid;
> 26
> 27 float data_in[NX][NY];
> 28
> 29 /* Loop indexes, and error handling. */
> 30 int x, y, retval;
> 31
> 32 // /* Open the file. NC_NOWRITE tells netCDF we want read-only access
> 33 // * to the file.*/
> 34 //
> 35 if ((retval = nc_open(FILE_NAME, NC_NOWRITE, &ncid)))
> 36 ERR(retval);
> 37
> 38 // /* Get the varid of the data variable, based on its name. */
> 39 if ((retval = nc_inq_varid(ncid, "TS", &varid)))
> 40 ERR(retval);
> 41 printf("varid is : %i \n",varid);
> 42 // /* Read the data. */
> 43 if ((retval = nc_get_var_float(ncid, varid, &data_in[0][0])))
> 44 ERR(retval);
> 45
> 46
> 47 // /* Close the file, freeing all resources. */
> 48 // if ((retval = nc_close(ncid)))
> 49 // ERR(retval);
> 50
> 51 printf("*** SUCCESS reading example file %s!\n", FILE_NAME);
> 52 return 0;
> 53 }
> =====
>
>
>
Russ Rew UCAR Unidata Program
address@hidden http://www.unidata.ucar.edu
Ticket Details
===================
Ticket ID: ZBT-271812
Department: Support netCDF
Priority: Critical
Status: Closed