1 /* This is part of the netCDF package. Copyright 2009 University
2 Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
3 conditions of use.
4
5 Test netcdf-4 coordinate variables and dimensions.
6
7 $Id: tst_coords.c,v 1.20 2010/03/30 16:25:41 ed Exp $
8 */
9
10 #include <nc_tests.h>
11 #include "err_macros.h"
12 #include "netcdf.h"
13
14 #define FILE_NAME "tst_coords.nc"
15
16 void
check_err(const int stat,const int line,const char * file)17 check_err(const int stat, const int line, const char *file) {
18 if (stat != NC_NOERR) {
19 (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
20 fflush(stderr);
21 exit(1);
22 }
23 }
24
25 #define INST_NAME "institution"
26 #define INSTITUTION "NCAR (National Center for Atmospheric \nResearch, Boulder, CO, USA)"
27
28 int
main(int argc,char ** argv)29 main(int argc, char **argv)
30 {
31 printf("\n*** Testing netcdf-4 coordinate variables and dimensions.\n");
32
33 printf("**** testing Jeff Whitakers reported 4.1 bug...");
34 {
35 #define NDIMS 2
36 #define NLAT 10
37 #define NLON 20
38 #define LAT_NAME "lat"
39 #define LON_NAME "lon"
40 #define NVARS 2
41 #define START_LAT 25.0
42 #define START_LON -125.0
43 {
44 int ncid, lon_dimid, lat_dimid;
45 int lat_varid, lon_varid;
46 float lats[NLAT], lons[NLON];
47 int lat, lon;
48 int nvars, ndims, ngatts, unlimdimid, nvars_in, varids_in[NVARS];
49 int ndims_in, natts_in, dimids_in[NDIMS];
50 char var_name_in[NC_MAX_NAME + 1];
51 nc_type xtype_in;
52
53 /* Initialize coord data. */
54 for (lat = 0; lat < NLAT; lat++)
55 lats[lat] = START_LAT + 5. * lat;
56 for (lon = 0; lon < NLON; lon++)
57 lons[lon] = START_LON + 5. * lon;
58
59 /* Create file with two dimensions. */
60 if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
61 if (nc_def_dim(ncid, LAT_NAME, NLAT, &lat_dimid)) ERR;
62 if (nc_def_dim(ncid, LON_NAME, NLON, &lon_dimid)) ERR;
63
64 if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, &lon_dimid, &lon_varid)) ERR;
65
66 /* Define and write longitude coord variable. */
67 if (nc_put_var_float(ncid, lon_varid, &lons[0])) ERR;
68
69 /* Define and write latitude coord variable. */
70 if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, &lat_dimid, &lat_varid)) ERR;
71 if (nc_put_var_float(ncid, lat_varid, &lats[0])) ERR;
72
73 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
74 if (nvars != 2 || ndims != 2 || ngatts != 0 || unlimdimid != -1) ERR;
75 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
76 if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
77 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
78 if (strcmp(var_name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
79 dimids_in[0] != 1 || natts_in != 0) ERR;
80
81 /* Close the file. */
82 if (nc_close(ncid)) ERR;
83
84 /* Re-open and check the file. */
85 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
86
87 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
88 if (nvars != 2 || ndims != 2 || ngatts != 0 || unlimdimid != -1) ERR;
89 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
90 if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
91 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
92 if (strcmp(var_name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
93 dimids_in[0] != 1 || natts_in != 0) ERR;
94
95 if (nc_close(ncid)) ERR;
96 }
97
98 }
99 SUMMARIZE_ERR;
100 printf("**** testing setting cache values for coordinate variables...");
101 {
102 #define RANK_1 1
103 #define DIM0_NAME "d0"
104 #define CACHE_SIZE 1000000
105 #define CACHE_NELEMS 1009
106 #define CACHE_PREEMPTION .90
107
108 int ncid, dimid, varid;
109 char name_in[NC_MAX_NAME + 1];
110
111 /* Create a test file with one dim and coord variable. */
112 if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;
113 if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid)) ERR;
114 if (nc_def_var(ncid, DIM0_NAME, NC_DOUBLE, 1, &dimid, &varid)) ERR;
115 if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
116 if (nc_close(ncid)) ERR;
117
118 /* Reopen the file and check. */
119 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
120 if (nc_inq_varname(ncid, 0, name_in)) ERR;
121 if (strcmp(name_in, DIM0_NAME)) ERR;
122 if (nc_set_var_chunk_cache(ncid, 0, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
123 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
124 if (strcmp(name_in, DIM0_NAME)) ERR;
125 if (nc_close(ncid)) ERR;
126 }
127 SUMMARIZE_ERR;
128 printf("**** testing multi-line strings in attributes...");
129 {
130 int ncid_classic, ncid_nc4;
131 /*int attid;*/
132 char att_in_classic[NC_MAX_NAME + 1], att_in_nc4[NC_MAX_NAME + 1];
133
134 #define FILE_CLASSIC "tst_coords_classic_att.nc"
135 #define FILE_NC4 "tst_coords_nc4_att.nc"
136 /* Create a classic and a netcdf-4 file. */
137 if (nc_create(FILE_CLASSIC, 0, &ncid_classic)) ERR;
138 if (nc_create(FILE_NC4, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid_nc4)) ERR;
139
140 /* Write an att to both. */
141 if (nc_put_att_text(ncid_classic, NC_GLOBAL, INST_NAME, strlen(INSTITUTION) + 1, INSTITUTION)) ERR;
142 if (nc_put_att_text(ncid_nc4, NC_GLOBAL, INST_NAME, strlen(INSTITUTION) + 1, INSTITUTION)) ERR;
143
144 /* Close them. */
145 if (nc_close(ncid_classic)) ERR;
146 if (nc_close(ncid_nc4)) ERR;
147
148 /* Reopen the files. */
149 if (nc_open(FILE_CLASSIC, 0, &ncid_classic)) ERR;
150 if (nc_open(FILE_NC4, 0, &ncid_nc4)) ERR;
151
152 /* I'll show you mine, if you show me yours... */
153 if (nc_get_att_text(ncid_classic, NC_GLOBAL, INST_NAME, att_in_classic)) ERR;
154 if (nc_get_att_text(ncid_nc4, NC_GLOBAL, INST_NAME, att_in_nc4)) ERR;
155 if (strcmp(att_in_classic, INSTITUTION) || strcmp(att_in_nc4, INSTITUTION) ||
156 strcmp(att_in_classic, att_in_nc4)) ERR;
157 if (memcmp(att_in_classic, att_in_nc4, strlen(INSTITUTION) + 1)) ERR;
158
159 /* Close them. */
160 if (nc_close(ncid_classic)) ERR;
161 if (nc_close(ncid_nc4)) ERR;
162 }
163 SUMMARIZE_ERR;
164 printf("**** testing ar-4 example metadata with ncgen-generated code...");
165 {
166 int stat; /* return status */
167 int ncid; /* netCDF id */
168
169 /* group ids */
170 int root_grp;
171
172 /* dimension ids */
173 int lon_dim;
174 int lat_dim;
175 int bnds_dim;
176 int time_dim;
177
178 /* dimension lengths */
179 size_t lon_len = 256;
180 size_t lat_len = 128;
181 size_t bnds_len = 2;
182 size_t time_len = NC_UNLIMITED;
183
184 /* variable ids */
185 int lon_bnds_id;
186 int lat_bnds_id;
187 int time_bnds_id;
188 int time_id;
189 int lat_id;
190 int lon_id;
191 int pr_id;
192
193 /* rank (number of dimensions) for each variable */
194 # define RANK_lon_bnds 2
195 # define RANK_lat_bnds 2
196 # define RANK_time_bnds 2
197 # define RANK_time 1
198 # define RANK_lat 1
199 # define RANK_lon 1
200 # define RANK_pr 3
201
202 /* variable shapes */
203 int lon_bnds_dims[RANK_lon_bnds];
204 int lat_bnds_dims[RANK_lat_bnds];
205 int time_bnds_dims[RANK_time_bnds];
206 int time_dims[RANK_time];
207 int lat_dims[RANK_lat];
208 int lon_dims[RANK_lon];
209 int pr_dims[RANK_pr];
210
211 /* enter define mode */
212 stat = nc_create(FILE_NAME, NC_NETCDF4 | NC_CLASSIC_MODEL, &ncid);
213 check_err(stat,__LINE__,__FILE__);
214 root_grp = ncid;
215
216 /* define dimensions */
217 stat = nc_def_dim(root_grp, "lon", lon_len, &lon_dim);
218 check_err(stat,__LINE__,__FILE__);
219 stat = nc_def_dim(root_grp, "lat", lat_len, &lat_dim);
220 check_err(stat,__LINE__,__FILE__);
221 stat = nc_def_dim(root_grp, "bnds", bnds_len, &bnds_dim);
222 check_err(stat,__LINE__,__FILE__);
223 stat = nc_def_dim(root_grp, "time", time_len, &time_dim);
224 check_err(stat,__LINE__,__FILE__);
225
226 /* define variables */
227
228 lon_bnds_dims[0] = lon_dim;
229 lon_bnds_dims[1] = bnds_dim;
230 stat = nc_def_var(root_grp, "lon_bnds", NC_DOUBLE, RANK_lon_bnds, lon_bnds_dims, &lon_bnds_id);
231 check_err(stat,__LINE__,__FILE__);
232
233 lat_bnds_dims[0] = lat_dim;
234 lat_bnds_dims[1] = bnds_dim;
235 stat = nc_def_var(root_grp, "lat_bnds", NC_DOUBLE, RANK_lat_bnds, lat_bnds_dims, &lat_bnds_id);
236 check_err(stat,__LINE__,__FILE__);
237
238 time_bnds_dims[0] = time_dim;
239 time_bnds_dims[1] = bnds_dim;
240 stat = nc_def_var(root_grp, "time_bnds", NC_DOUBLE, RANK_time_bnds, time_bnds_dims, &time_bnds_id);
241 check_err(stat,__LINE__,__FILE__);
242
243 time_dims[0] = time_dim;
244 stat = nc_def_var(root_grp, "time", NC_DOUBLE, RANK_time, time_dims, &time_id);
245 check_err(stat,__LINE__,__FILE__);
246
247 lat_dims[0] = lat_dim;
248 stat = nc_def_var(root_grp, "lat", NC_DOUBLE, RANK_lat, lat_dims, &lat_id);
249 check_err(stat,__LINE__,__FILE__);
250
251 lon_dims[0] = lon_dim;
252 stat = nc_def_var(root_grp, "lon", NC_DOUBLE, RANK_lon, lon_dims, &lon_id);
253 check_err(stat,__LINE__,__FILE__);
254
255 pr_dims[0] = time_dim;
256 pr_dims[1] = lat_dim;
257 pr_dims[2] = lon_dim;
258 stat = nc_def_var(root_grp, "pr", NC_FLOAT, RANK_pr, pr_dims, &pr_id);
259 check_err(stat,__LINE__,__FILE__);
260
261 /* assign global attributes */
262 { /* table_id */
263 static const char table_id_att[8] = {"Table A1"} ;
264 stat = nc_put_att_text(root_grp, NC_GLOBAL, "table_id", 8, table_id_att);
265 check_err(stat,__LINE__,__FILE__);
266 }
267 { /* title */
268 static const char title_att[34] = {"model output prepared for IPCC AR4"} ;
269 stat = nc_put_att_text(root_grp, NC_GLOBAL, "title", 34, title_att);
270 check_err(stat,__LINE__,__FILE__);
271 }
272 { /* institution */
273 static const char institution_att[66] = {INSTITUTION} ;
274 stat = nc_put_att_text(root_grp, NC_GLOBAL, INST_NAME, 66, institution_att);
275 check_err(stat,__LINE__,__FILE__);
276 }
277 { /* source */
278 static const char source_att[153] = {"CCSM3.0, version vector05 (2004): \natmosphere: CAM3.0, T85L26;\nocean : POP1.4.3 (modified), gx1v3\nsea ice : CSIM5.0, gx1v3;\nland : CLM3.0, T85"} ;
279 stat = nc_put_att_text(root_grp, NC_GLOBAL, "source", 153, source_att);
280 check_err(stat,__LINE__,__FILE__);
281 }
282 { /* contact */
283 static const char contact_att[13] = {"ccsm@ucar.edu"} ;
284 stat = nc_put_att_text(root_grp, NC_GLOBAL, "contact", 13, contact_att);
285 check_err(stat,__LINE__,__FILE__);
286 }
287 { /* project_id */
288 static const char project_id_att[22] = {"IPCC Fourth Assessment"} ;
289 stat = nc_put_att_text(root_grp, NC_GLOBAL, "project_id", 22, project_id_att);
290 check_err(stat,__LINE__,__FILE__);
291 }
292 { /* Conventions */
293 static const char Conventions_att[6] = {"CF-1.0"} ;
294 stat = nc_put_att_text(root_grp, NC_GLOBAL, "Conventions", 6, Conventions_att);
295 check_err(stat,__LINE__,__FILE__);
296 }
297 { /* references */
298 static const char references_att[137] = {"Collins, W.D., et al., 2005:\n The Community Climate System Model, Version 3\n Journal of Climate\n \n Main website: http://www.ccsm.ucar.edu"} ;
299 stat = nc_put_att_text(root_grp, NC_GLOBAL, "references", 137, references_att);
300 check_err(stat,__LINE__,__FILE__);
301 }
302 { /* acknowledgment */
303 static const char acknowledgment_att[847] = {" Any use of CCSM data should acknowledge the contribution\n of the CCSM project and CCSM sponsor agencies with the \n following citation:\n 'This research uses data provided by the Community Climate\n System Model project (www.ccsm.ucar.edu), supported by the\n Directorate for Geosciences of the National Science Foundation\n and the Office of Biological and Environmental Research of\n the U.S. Department of Energy.'\nIn addition, the words 'Community Climate System Model' and\n 'CCSM' should be included as metadata for webpages referencing\n work using CCSM data or as keywords provided to journal or book\npublishers of your manuscripts.\nUsers of CCSM data accept the responsibility of emailing\n citations of publications of research using CCSM data to\n ccsm@ucar.edu.\nAny redistribution of CCSM data must include this data\n acknowledgement statement."} ;
304 stat = nc_put_att_text(root_grp, NC_GLOBAL, "acknowledgment", 847, acknowledgment_att);
305 check_err(stat,__LINE__,__FILE__);
306 }
307 { /* realization */
308 static const int realization_att[1] = {8} ;
309 stat = nc_put_att_int(root_grp, NC_GLOBAL, "realization", NC_INT, 1, realization_att);
310 check_err(stat,__LINE__,__FILE__);
311 }
312 { /* experiment_id */
313 static const char experiment_id_att[46] = {"climate of the 20th Century experiment (20C3M)"} ;
314 stat = nc_put_att_text(root_grp, NC_GLOBAL, "experiment_id", 46, experiment_id_att);
315 check_err(stat,__LINE__,__FILE__);
316 }
317 { /* history */
318 static const char history_att[139] = {"Created from CCSM3 case b30.030g.ES01\n by strandwg@ucar.edu\n on Wed Sep 10 12:22:06 MDT 2008\n \n For all data, added IPCC requested metadata"} ;
319 stat = nc_put_att_text(root_grp, NC_GLOBAL, "history", 139, history_att);
320 check_err(stat,__LINE__,__FILE__);
321 }
322 { /* comment */
323 static const char comment_att[1105] = {"This simulation was initiated from year 460 of \n CCSM3 model run b30.020.ES01 and executed on \n hardware Earth Simulator Center, JAMSTEC. The input external forcings are\nozone forcing : mozart.o3.128x64_L18_1870-2000_c040515.nc\naerosol optics : AerosolOptics_c040105.nc\naerosol MMR : AerosolMass_V_128x256_clim_c031022.nc\ncarbon scaling : carbonscaling_1870-2000_c040225.nc\nsolar forcing : scon_lean_1870-2100_c040123.nc\nGHGs : ghg_1870_2100_c040122.nc\nGHG loss rates : noaamisc.r8.nc\nvolcanic forcing : VolcanicMass_1870-1999_64x1_L18_c040123.nc\nDMS emissions : DMS_emissions_128x256_clim_c040122.nc\noxidants : oxid_128x256_L26_clim_c040112.nc\nSOx emissions : SOx_emissions_128x256_L2_1850-2000_c040321.nc\n Physical constants used for derived data:\n Lv (latent heat of evaporation): 2.501e6 J kg-1\n Lf (latent heat of fusion ): 3.337e5 J kg-1\n r[h2o] (density of water ): 1000 kg m-3\n g2kg (grams to kilograms ): 1000 g kg-1\n \n Integrations were performed by NCAR and CRIEPI with support\n and facilities provided by NSF, DOE, MEXT and ESC/JAMSTEC."} ;
324 stat = nc_put_att_text(root_grp, NC_GLOBAL, "comment", 1105, comment_att);
325 check_err(stat,__LINE__,__FILE__);
326 }
327
328
329 /* assign per-variable attributes */
330 { /* calendar */
331 static const char time_calendar_att[6] = {"noleap"} ;
332 stat = nc_put_att_text(root_grp, time_id, "calendar", 6, time_calendar_att);
333 check_err(stat,__LINE__,__FILE__);
334 }
335 { /* standard_name */
336 static const char time_standard_name_att[4] = {"time"} ;
337 stat = nc_put_att_text(root_grp, time_id, "standard_name", 4, time_standard_name_att);
338 check_err(stat,__LINE__,__FILE__);
339 }
340 { /* axis */
341 static const char time_axis_att[1] = {"T"} ;
342 stat = nc_put_att_text(root_grp, time_id, "axis", 1, time_axis_att);
343 check_err(stat,__LINE__,__FILE__);
344 }
345 { /* units */
346 static const char time_units_att[19] = {"days since 0000-1-1"} ;
347 stat = nc_put_att_text(root_grp, time_id, "units", 19, time_units_att);
348 check_err(stat,__LINE__,__FILE__);
349 }
350 { /* bounds */
351 static const char time_bounds_att[9] = {"time_bnds"} ;
352 stat = nc_put_att_text(root_grp, time_id, "bounds", 9, time_bounds_att);
353 check_err(stat,__LINE__,__FILE__);
354 }
355 { /* long_name */
356 static const char time_long_name_att[4] = {"time"} ;
357 stat = nc_put_att_text(root_grp, time_id, "long_name", 4, time_long_name_att);
358 check_err(stat,__LINE__,__FILE__);
359 }
360 { /* axis */
361 static const char lat_axis_att[1] = {"Y"} ;
362 stat = nc_put_att_text(root_grp, lat_id, "axis", 1, lat_axis_att);
363 check_err(stat,__LINE__,__FILE__);
364 }
365 { /* standard_name */
366 static const char lat_standard_name_att[8] = {"latitude"} ;
367 stat = nc_put_att_text(root_grp, lat_id, "standard_name", 8, lat_standard_name_att);
368 check_err(stat,__LINE__,__FILE__);
369 }
370 { /* bounds */
371 static const char lat_bounds_att[8] = {"lat_bnds"} ;
372 stat = nc_put_att_text(root_grp, lat_id, "bounds", 8, lat_bounds_att);
373 check_err(stat,__LINE__,__FILE__);
374 }
375 { /* long_name */
376 static const char lat_long_name_att[8] = {"latitude"} ;
377 stat = nc_put_att_text(root_grp, lat_id, "long_name", 8, lat_long_name_att);
378 check_err(stat,__LINE__,__FILE__);
379 }
380 { /* units */
381 static const char lat_units_att[13] = {"degrees_north"} ;
382 stat = nc_put_att_text(root_grp, lat_id, "units", 13, lat_units_att);
383 check_err(stat,__LINE__,__FILE__);
384 }
385 { /* axis */
386 static const char lon_axis_att[1] = {"X"} ;
387 stat = nc_put_att_text(root_grp, lon_id, "axis", 1, lon_axis_att);
388 check_err(stat,__LINE__,__FILE__);
389 }
390 { /* standard_name */
391 static const char lon_standard_name_att[9] = {"longitude"} ;
392 stat = nc_put_att_text(root_grp, lon_id, "standard_name", 9, lon_standard_name_att);
393 check_err(stat,__LINE__,__FILE__);
394 }
395 { /* bounds */
396 static const char lon_bounds_att[8] = {"lon_bnds"} ;
397 stat = nc_put_att_text(root_grp, lon_id, "bounds", 8, lon_bounds_att);
398 check_err(stat,__LINE__,__FILE__);
399 }
400 { /* long_name */
401 static const char lon_long_name_att[9] = {"longitude"} ;
402 stat = nc_put_att_text(root_grp, lon_id, "long_name", 9, lon_long_name_att);
403 check_err(stat,__LINE__,__FILE__);
404 }
405 { /* units */
406 static const char lon_units_att[12] = {"degrees_east"} ;
407 stat = nc_put_att_text(root_grp, lon_id, "units", 12, lon_units_att);
408 check_err(stat,__LINE__,__FILE__);
409 }
410 { /* comment */
411 static const char pr_comment_att[60] = {"Created using NCL code CCSM_atmm_2cf.ncl on\n machine mineral"} ;
412 stat = nc_put_att_text(root_grp, pr_id, "comment", 60, pr_comment_att);
413 check_err(stat,__LINE__,__FILE__);
414 }
415 { /* missing_value */
416 static const float pr_missing_value_att[1] = {1e+20} ;
417 stat = nc_put_att_float(root_grp, pr_id, "missing_value", NC_FLOAT, 1, pr_missing_value_att);
418 check_err(stat,__LINE__,__FILE__);
419 }
420 { /* _FillValue */
421 static const float pr_FillValue_att[1] = {1e+20} ;
422 stat = nc_put_att_float(root_grp, pr_id, "_FillValue", NC_FLOAT, 1, pr_FillValue_att);
423 check_err(stat,__LINE__,__FILE__);
424 }
425 { /* cell_methods */
426 static const char pr_cell_methods_att[30] = {"time: mean (interval: 1 month)"} ;
427 stat = nc_put_att_text(root_grp, pr_id, "cell_methods", 30, pr_cell_methods_att);
428 check_err(stat,__LINE__,__FILE__);
429 }
430 { /* history */
431 static const char pr_history_att[20] = {"(PRECC+PRECL)*r[h2o]"} ;
432 stat = nc_put_att_text(root_grp, pr_id, "history", 20, pr_history_att);
433 check_err(stat,__LINE__,__FILE__);
434 }
435 { /* original_units */
436 static const char pr_original_units_att[7] = {"m-1 s-1"} ;
437 stat = nc_put_att_text(root_grp, pr_id, "original_units", 7, pr_original_units_att);
438 check_err(stat,__LINE__,__FILE__);
439 }
440 { /* original_name */
441 static const char pr_original_name_att[12] = {"PRECC, PRECL"} ;
442 stat = nc_put_att_text(root_grp, pr_id, "original_name", 12, pr_original_name_att);
443 check_err(stat,__LINE__,__FILE__);
444 }
445 { /* standard_name */
446 static const char pr_standard_name_att[18] = {"precipitation_flux"} ;
447 stat = nc_put_att_text(root_grp, pr_id, "standard_name", 18, pr_standard_name_att);
448 check_err(stat,__LINE__,__FILE__);
449 }
450 { /* units */
451 static const char pr_units_att[10] = {"kg m-2 s-1"} ;
452 stat = nc_put_att_text(root_grp, pr_id, "units", 10, pr_units_att);
453 check_err(stat,__LINE__,__FILE__);
454 }
455 { /* long_name */
456 static const char pr_long_name_att[18] = {"precipitation_flux"} ;
457 stat = nc_put_att_text(root_grp, pr_id, "long_name", 18, pr_long_name_att);
458 check_err(stat,__LINE__,__FILE__);
459 }
460 { /* cell_method */
461 static const char pr_cell_method_att[10] = {"time: mean"} ;
462 stat = nc_put_att_text(root_grp, pr_id, "cell_method", 10, pr_cell_method_att);
463 check_err(stat,__LINE__,__FILE__);
464 }
465
466 /* don't initialize variables with fill values */
467 stat = nc_set_fill(root_grp, NC_NOFILL, 0);
468 check_err(stat,__LINE__,__FILE__);
469
470 /* leave define mode */
471 stat = nc_enddef (root_grp);
472 check_err(stat,__LINE__,__FILE__);
473
474 stat = nc_close(root_grp);
475 check_err(stat,__LINE__,__FILE__);
476
477 {
478 #define NDIMS4 4
479 int ndims, dimids_in[NDIMS4];
480 char name_in[NC_MAX_NAME + 1];
481 char institution_att_in[NC_MAX_NAME + 1];
482
483 /* Now open this file and check order of dimensions. */
484 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
485
486 /* Check dimids. */
487 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
488 if (strcmp(name_in, "lon")) ERR;
489 if (nc_inq_dimname(ncid, 1, name_in)) ERR;
490 if (strcmp(name_in, "lat")) ERR;
491 if (nc_inq_dimname(ncid, 2, name_in)) ERR;
492 if (strcmp(name_in, "bnds")) ERR;
493 if (nc_inq_dimname(ncid, 3, name_in)) ERR;
494 if (strcmp(name_in, "time")) ERR;
495
496 /* Check inq_dimids function. */
497 if (nc_inq_dimids(ncid, &ndims, dimids_in, 0)) ERR;
498 if (ndims != NDIMS4 || dimids_in[0] != 0 || dimids_in[1] != 1 ||
499 dimids_in[2] != 2 || dimids_in[3] != 3) ERR;
500
501 /* Check attribute with line breaks. */
502 if (nc_get_att_text(ncid, NC_GLOBAL, INST_NAME,
503 institution_att_in)) ERR;
504 if (strncmp(institution_att_in, INSTITUTION, strlen(INSTITUTION))) ERR;
505
506 if (nc_close(ncid)) ERR;
507 }
508
509 }
510 SUMMARIZE_ERR;
511 printf("**** testing dim order when coord vars are defined in the wrong order...");
512 {
513 #define RANK_2 2
514 #define DIM0 "d0"
515 #define DIM1 "d1"
516 int ncid, dimids[RANK_2], varid[RANK_2];
517 char name_in[NC_MAX_NAME + 1];
518
519 /* Create a test file. */
520 if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;
521
522 /* Define dimensions in order. */
523 if (nc_def_dim(ncid, DIM0, NC_UNLIMITED, &dimids[0])) ERR;
524 if (nc_def_dim(ncid, DIM1, 4, &dimids[1])) ERR;
525
526 /* Define coordinate variables in a different order. */
527 if (nc_def_var(ncid, DIM1, NC_DOUBLE, 1, &dimids[1], &varid[1])) ERR;
528 if (nc_def_var(ncid, DIM0, NC_DOUBLE, 1, &dimids[0], &varid[0])) ERR;
529
530 /* That's it! */
531 if (nc_close(ncid)) ERR;
532
533 /* Reopen the file and check dimension order. */
534 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
535
536 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
537 if (strcmp(name_in, DIM0)) ERR;
538 if (nc_inq_dimname(ncid, 1, name_in)) ERR;
539 if (strcmp(name_in, DIM1)) ERR;
540
541 if (nc_close(ncid)) ERR;
542 }
543 SUMMARIZE_ERR;
544 printf("**** testing order of coordinate dims...");
545 {
546 #define RANK_3 3
547 #define DIM1_NAME "d1"
548 #define DIM2_NAME "d2"
549 #define DIM3_NAME "d3"
550 int ncid, dimids[RANK_3], varid[RANK_3];
551 char name_in[NC_MAX_NAME + 1];
552
553 /* Create a 3D test file. */
554 if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;
555
556 /* Define dimensions in order. */
557 if (nc_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimids[0])) ERR;
558 if (nc_def_dim(ncid, DIM2_NAME, 4, &dimids[1])) ERR;
559 if (nc_def_dim(ncid, DIM3_NAME, 3, &dimids[2])) ERR;
560
561 /* Define coordinate variables in a different order. */
562 if (nc_def_var(ncid, DIM1_NAME, NC_DOUBLE, 1, &dimids[0], &varid[0])) ERR;
563 if (nc_def_var(ncid, DIM2_NAME, NC_DOUBLE, 1, &dimids[1], &varid[1])) ERR;
564 if (nc_def_var(ncid, DIM3_NAME, NC_DOUBLE, 1, &dimids[2], &varid[2])) ERR;
565
566 /* That's it! */
567 if (nc_close(ncid)) ERR;
568
569 /* Reopen the file and check dimension order. */
570 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
571
572 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
573 if (strcmp(name_in, DIM1_NAME)) ERR;
574 if (nc_inq_dimname(ncid, 1, name_in)) ERR;
575 if (strcmp(name_in, DIM2_NAME)) ERR;
576 if (nc_inq_dimname(ncid, 2, name_in)) ERR;
577 if (strcmp(name_in, DIM3_NAME)) ERR;
578
579 if (nc_close(ncid)) ERR;
580 }
581 SUMMARIZE_ERR;
582 printf("**** testing coordinate vars...");
583 {
584 # define RANK_Coordinates_lat 1
585 int ncid;
586 int Coordinates_grp;
587 int lat_dim;
588 size_t lat_len = 3;
589 int Coordinates_lat_id;
590
591 if(nc_create(FILE_NAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
592 if (nc_def_grp(ncid, "Coordinates", &Coordinates_grp)) ERR;
593
594 /* Define dimensions in root group. */
595 if (nc_def_dim(ncid, "lat", lat_len, &lat_dim)) ERR;
596
597 /* Define coordinate variable in Coordinates group. */
598 if (nc_def_var(Coordinates_grp, "lat", NC_FLOAT,
599 1, &lat_dim, &Coordinates_lat_id)) ERR;
600
601 if (nc_close(ncid)) ERR;
602 }
603 SUMMARIZE_ERR;
604 printf("**** testing 2D non-coordinate variable...");
605 {
606 #define VAR_NAME "Britany"
607 #define NDIMS 2
608 #define TEXT_LEN 15
609 #define D0_NAME "time"
610 #define D1_NAME "tl"
611 int ncid, nvars_in, varids_in[1];
612 int time_dimids[NDIMS], time_id;
613 size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
614 const char ttext[TEXT_LEN]="20051224.150000";
615 int nvars, ndims, ngatts, unlimdimid;
616 int ndims_in, natts_in, dimids_in[NDIMS];
617 char var_name_in[NC_MAX_NAME + 1];
618 nc_type xtype_in;
619
620 /* Create a netcdf-4 file with 2D coordinate var. */
621 if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
622
623 if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR;
624 if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR;
625 if (nc_def_var(ncid, VAR_NAME, NC_USHORT, NDIMS, time_dimids,
626 &time_id) != NC_ESTRICTNC3) ERR;
627 if (nc_def_var(ncid, VAR_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR;
628 if (nc_enddef(ncid)) ERR;
629
630 /* Write one time to the coordinate variable. */
631 time_count[0] = 1;
632 time_count[1] = TEXT_LEN;
633 if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;
634 if (nc_close(ncid)) ERR;
635
636 /* Open the file and check. */
637 if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
638 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
639 if (nvars != 1 || ndims != 2 || ngatts != 0 || unlimdimid != 0) ERR;
640 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
641 if (nvars_in != 1 || varids_in[0] != 0) ERR;
642 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
643 if (strcmp(var_name_in, VAR_NAME) || xtype_in != NC_CHAR || ndims_in != 2 ||
644 dimids_in[0] != 0 || dimids_in[1] != 1 || natts_in != 0) ERR;
645 if (nc_close(ncid)) ERR;
646 }
647 SUMMARIZE_ERR;
648 printf("**** testing 2D coordinate variable...");
649 {
650 #define NDIMS 2
651 #define TEXT_LEN 15
652 #define D0_NAME "time"
653 #define D1_NAME "tl"
654 int ncid, nvars_in, varids_in[1];
655 int time_dimids[NDIMS], time_id;
656 size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
657 const char ttext[TEXT_LEN + 1]="20051224.150000";
658 int nvars, ndims, ngatts, unlimdimid;
659 int ndims_in, natts_in, dimids_in[NDIMS];
660 char var_name_in[NC_MAX_NAME + 1];
661 nc_type xtype_in;
662
663 /* Create a netcdf-4 file with 2D coordinate var. */
664 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
665 if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR;
666 if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR;
667 if (nc_def_var(ncid, D0_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR;
668
669 /* Write one time to the coordinate variable. */
670 time_count[0] = 1;
671 time_count[1] = TEXT_LEN;
672 if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;
673 if (nc_close(ncid)) ERR;
674
675 /* Open the file and check. */
676 if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
677 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
678 if (nvars != 1 || ndims != 2 || ngatts != 0 || unlimdimid != 0) ERR;
679 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
680 if (nvars_in != 1 || varids_in[0] != 0) ERR;
681 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
682 if (strcmp(var_name_in, D0_NAME) || xtype_in != NC_CHAR || ndims_in != 2 ||
683 dimids_in[0] != 0 || dimids_in[1] != 1 || natts_in != 0) ERR;
684 if (nc_close(ncid)) ERR;
685 }
686 SUMMARIZE_ERR;
687 printf("**** testing new order of doing things with coordinate variable...");
688 {
689 /* In this test:
690 define a dimension
691 define a variable that uses that dimension
692 put values in the variable
693 define coordinate values for the dimension
694 */
695 #define VAR_NAME_BB "The_Birth_of_Britain"
696 #define NDIMS_1 1
697 #define TEXT_LEN 15
698 #define WINSTON_CHURCHILL "Winston_S_Churchill"
699 #define D0_LEN 2
700 #define NUM_VARS_2 2
701 int ncid, nvars_in, varids_in[NUM_VARS_2];
702 int dimid, varid, varid2;
703 int nvars, ndims, ngatts, unlimdimid;
704 int ndims_in, natts_in, dimids_in[NDIMS];
705 char var_name_in[NC_MAX_NAME + 1];
706 nc_type xtype_in;
707 int data[D0_LEN] = {42, -42};
708
709 /* Create a netcdf-4 file with 2D coordinate var. */
710 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
711 if (nc_def_dim(ncid, WINSTON_CHURCHILL, NC_UNLIMITED, &dimid)) ERR;
712 if (nc_def_var(ncid, VAR_NAME, NC_INT, NDIMS_1, &dimid, &varid)) ERR;
713 if (nc_put_var_int(ncid, varid, data)) ERR;
714 if (nc_def_var(ncid, WINSTON_CHURCHILL, NC_INT, NDIMS_1, &dimid, &varid2)) ERR;
715 if (nc_put_var_int(ncid, varid2, data)) ERR;
716
717 /* Check things. */
718 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
719 if (nvars != 2 || ndims != 1 || ngatts != 0 || unlimdimid != 0) ERR;
720 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
721 if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
722 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
723 if (strcmp(var_name_in, VAR_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
724 dimids_in[0] != 0 || natts_in != 0) ERR;
725
726 if (nc_close(ncid)) ERR;
727
728 /* Open the file and check. */
729 if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
730 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
731 if (nvars != 2 || ndims != 1 || ngatts != 0 || unlimdimid != 0) ERR;
732 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
733 if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
734 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
735 if (strcmp(var_name_in, VAR_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
736 dimids_in[0] != 0 || natts_in != 0) ERR;
737 if (nc_close(ncid)) ERR;
738 }
739 SUMMARIZE_ERR;
740 printf("**** testing 2D coordinate variable with dimensions defined in different order...");
741 {
742 #define NDIMS 2
743 #define TEXT_LEN 15
744 #define D0_NAME "time"
745 #define D1_NAME "tl"
746 #define NUM_VARS 2
747 int ncid, nvars_in, varids_in[NUM_VARS];
748 int time_dimids[NDIMS], time_id, tl_id;
749 size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
750 const char ttext[TEXT_LEN + 1]="20051224.150000";
751 char ttext_in[TEXT_LEN + 1];
752 int nvars, ndims, ngatts, unlimdimid;
753 int ndims_in, natts_in, dimids_in[NDIMS];
754 char var_name_in[NC_MAX_NAME + 1], dim_name_in[NC_MAX_NAME + 1];
755 size_t len_in;
756 nc_type xtype_in;
757
758 /* Create a netcdf-4 file with 2D coordinate var. */
759 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
760 if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR;
761 if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR;
762 if (nc_def_var(ncid, D0_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR;
763 if (nc_def_var(ncid, D1_NAME, NC_CHAR, 1, &time_dimids[0], &tl_id)) ERR;
764
765 /* Write one time to the coordinate variable. */
766 time_count[0] = 1;
767 time_count[1] = TEXT_LEN;
768 if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;
769
770 /* Check the data. */
771 if (nc_get_vara_text(ncid, time_id, time_index, time_count, ttext_in)) ERR;
772 if (strncmp(ttext, ttext_in, TEXT_LEN)) ERR;
773
774 /* Close up. */
775 if (nc_close(ncid)) ERR;
776
777 /* Open the file and check. */
778 if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
779 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
780 if (nvars != NUM_VARS || ndims != NDIMS || ngatts != 0 || unlimdimid != 1) ERR;
781 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
782 if (nvars_in != NUM_VARS || varids_in[0] != 0 || varids_in[1] != 1) ERR;
783 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
784 if (strcmp(var_name_in, D0_NAME) || xtype_in != NC_CHAR || ndims_in != NDIMS ||
785 dimids_in[0] != 1 || dimids_in[1] != 0 || natts_in != 0) ERR;
786 if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
787 if (ndims_in != NDIMS || dimids_in[0] != 0 || dimids_in[1] != 1) ERR;
788 if (nc_inq_dim(ncid, 0, dim_name_in, &len_in)) ERR;
789 if (strcmp(dim_name_in, D1_NAME) || len_in != TEXT_LEN) ERR;
790 if (nc_inq_dim(ncid, 1, dim_name_in, &len_in)) ERR;
791 if (strcmp(dim_name_in, D0_NAME) || len_in != 1) ERR;
792
793 /* Check the data. */
794 if (nc_get_vara_text(ncid, time_id, time_index, time_count, ttext_in)) ERR;
795 if (strncmp(ttext, ttext_in, TEXT_LEN)) ERR;
796
797 /* Close up. */
798 if (nc_close(ncid)) ERR;
799 }
800 SUMMARIZE_ERR;
801 FINAL_RESULTS;
802 }
803