1/** \file
2Dimension functions
3
4These functions define and inquire about dimensions.
5
6Copyright 2010 University Corporation for Atmospheric
7Research/Unidata. See COPYRIGHT file for more info.
8*/
9
10#include "ncdispatch.h"
11
12/*! \defgroup dimensions Dimensions
13
14Dimensions are used to define the shape of data in netCDF.
15
16Dimensions for a netCDF dataset are defined when it is created, while
17the netCDF dataset is in define mode. Additional dimensions may be
18added later by reentering define mode. A netCDF dimension has a name
19and a length. In a netCDF classic or 64-bit offset file, at most one
20dimension can have the unlimited length, which means variables using
21this dimension can grow along this dimension. In a netCDF-4 file
22multiple unlimited dimensions are supported.
23
24There is a suggested limit (1024) to the number of dimensions that can
25be defined in a single netCDF dataset. The limit is the value of the
26predefined macro NC_MAX_DIMS. The purpose of the limit is to make
27writing generic applications simpler. They need only provide an array
28of NC_MAX_DIMS dimensions to handle any netCDF dataset. The
29implementation of the netCDF library does not enforce this advisory
30maximum, so it is possible to use more dimensions, if necessary, but
31netCDF utilities that assume the advisory maximums may not be able to
32handle the resulting netCDF datasets.
33
34NC_MAX_VAR_DIMS, which must not exceed NC_MAX_DIMS, is the maximum
35number of dimensions that can be used to specify the shape of a single
36variable.  It is also intended to simplify writing generic
37applications.
38
39Ordinarily, the name and length of a dimension are fixed when the
40dimension is first defined. The name may be changed later, but the
41length of a dimension (other than the unlimited dimension) cannot be
42changed without copying all the data to a new netCDF dataset with a
43redefined dimension length.
44
45Dimension lengths in the C interface are type size_t rather than type
46int to make it possible to access all the data in a netCDF dataset on
47a platform that only supports a 16-bit int data type, for example
48MSDOS. If dimension lengths were type int instead, it would not be
49possible to access data from variables with a dimension length greater
50than a 16-bit int can accommodate.
51
52A netCDF dimension in an open netCDF dataset is referred to by a small
53integer called a dimension ID. In the C interface, dimension IDs are
540, 1, 2, ..., in the order in which the dimensions were defined.
55
56Operations supported on dimensions are:
57- Create a dimension, given its name and length.
58- Get a dimension ID from its name.
59- Get a dimension's name and length from its ID.
60- Rename a dimension.
61
62*/
63
64/*! \{*/ /* All these functions are part of the above defgroup... */
65
66/** \name Deleting and Renaming Dimensions
67
68Functions to delete or rename an dimension. */
69/*! \{ */ /* All these functions are part of this named group... */
70
71/*!
72
73Define a new dimension. The function nc_def_dim adds a new
74dimension to an open netCDF dataset in define mode. It returns (as an
75argument) a dimension ID, given the netCDF ID, the dimension name, and
76the dimension length. At most one unlimited length dimension, called
77the record dimension, may be defined for each classic or 64-bit offset
78netCDF dataset. NetCDF-4 datasets may have multiple unlimited
79dimensions.
80
81\param ncid NetCDF or group ID, from a previous call to nc_open(),
82nc_create(), nc_def_grp(), or associated inquiry functions such as
83nc_inq_ncid().
84
85\param name Name of the dimension to be created.
86
87\param len Length of the dimension to be created. Use NC_UNLIMITED for
88unlimited dimensions.
89
90\param idp Pointer where dimension ID will be stored.
91
92\retval ::NC_NOERR No error.
93\returns ::NC_EBADID Not a valid ID.
94\returns ::NC_ENOTINDEFINE Not in define mode.
95\returns ::NC_EDIMSIZE Invalid dimension size.
96\returns ::NC_EUNLIMIT NC_UNLIMITED size already in use
97\returns ::NC_EMAXDIMS NC_MAX_DIMS exceeded
98\returns ::NC_ENAMEINUSE String match to name in use
99\returns ::NC_ENOMEM Memory allocation (malloc) failure
100\returns ::NC_EPERM Write to read only
101
102\section nc_def_dim_example Example
103
104Here is an example using nc_def_dim() to create a dimension named lat of
105length 18 and a unlimited dimension named rec in a new netCDF dataset
106named foo.nc:
107
108\code
109     #include <netcdf.h>
110        ...
111     int status, ncid, latid, recid;
112        ...
113     status = nc_create("foo.nc", NC_NOCLOBBER, &ncid);
114     if (status != NC_NOERR) handle_error(status);
115        ...
116     status = nc_def_dim(ncid, "lat", 18L, &latid);
117     if (status != NC_NOERR) handle_error(status);
118     status = nc_def_dim(ncid, "rec", NC_UNLIMITED, &recid);
119     if (status != NC_NOERR) handle_error(status);
120\endcode
121
122 */
123int
124nc_def_dim(int ncid, const char *name, size_t len, int *idp)
125{
126    NCncp;
127    int stat = NC_check_id(ncid, &ncp);
128    if(stat != NC_NOERR) return stat;
129    TRACE(nc_def_dim);
130    return ncp->dispatch->def_dim(ncidnamelenidp);
131}
132
133/*!
134Find the ID of a dimension from the name.
135
136The function nc_inq_dimid returns (as an argument) the ID of a netCDF
137dimension, given the name of the dimension. If ndims is the number of
138dimensions defined for a netCDF dataset, each dimension has an ID
139between 0 and ndims-1.
140
141\param ncid NetCDF or group ID, from a previous call to nc_open(),
142nc_create(), nc_def_grp(), or associated inquiry functions such as
143nc_inq_ncid().
144
145\param name Name of the dimension.
146
147\param idp Pointer where dimension ID will be stored.
148
149\returns ::NC_NOERR   No error.
150\returns ::NC_EBADID  Not a valid ID.
151\returns ::NC_EBADDIM Invalid dimension ID or name.
152 */
153int
154nc_inq_dimid(int ncid, const char *name, int *idp)
155{
156    NCncp;
157    int stat = NC_check_id(ncid, &ncp);
158    if(stat != NC_NOERR) return stat;
159    TRACE(nc_inq_dimid);
160    return ncp->dispatch->inq_dimid(ncid,name,idp);
161}
162
163/*!
164Find the name and length of a dimension.
165
166The length for the unlimited dimension, if any, is the number of
167records written so far.
168
169\param ncid NetCDF or group ID, from a previous call to nc_open(),
170nc_create(), nc_def_grp(), or associated inquiry functions such as
171nc_inq_ncid().
172
173\param dimid Dimension ID, from a previous call to nc_inq_dimid() or
174nc_def_dim().
175
176\param name Returned dimension name. The caller must allocate space
177for the returned name. The maximum possible length, in characters, of
178a dimension name is given by the predefined constant
179NC_MAX_NAME. (This doesn't include the null terminator, so declare
180your array to be size NC_MAX_NAME+1). The returned character array
181will be null-terminated.
182
183\param lenp Pointer to location for returned length of dimension. For
184the unlimited dimension, this is the number of records written so far.
185
186\returns ::NC_NOERR   No error.
187\returns ::NC_EBADID  Not a valid ID.
188\returns ::NC_EBADDIM Invalid dimension ID or name.
189
190\section nc_inq_dim_example Example
191
192Here is an example using nc_inq_dim() to determine the length of a
193dimension named lat, and the name and current maximum length of the
194unlimited dimension for an existing netCDF dataset named foo.nc:
195
196\code
197     #include <netcdf.h>
198        ...
199     int status, ncid, latid, recid;
200     size_t latlength, recs;
201     char recname[NC_MAX_NAME+1];
202        ...
203     status = nc_open("foo.nc", NC_NOWRITE, &ncid);
204     if (status != NC_NOERR) handle_error(status);
205     status = nc_inq_unlimdim(ncid, &recid);
206     if (status != NC_NOERR) handle_error(status);
207        ...
208     status = nc_inq_dimid(ncid, "lat", &latid);
209     if (status != NC_NOERR) handle_error(status);
210     status = nc_inq_dimlen(ncid, latid, &latlength);
211     if (status != NC_NOERR) handle_error(status);
212
213     status = nc_inq_dim(ncid, recid, recname, &recs);
214     if (status != NC_NOERR) handle_error(status);
215\endcode
216 */
217int
218nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
219{
220    NCncp;
221    int stat = NC_check_id(ncid, &ncp);
222    if(stat != NC_NOERR) return stat;
223    TRACE(nc_inq_dim);
224    return ncp->dispatch->inq_dim(ncid,dimid,name,lenp);
225}
226
227/*!
228Rename a dimension.
229
230This function renames an existing dimension in a netCDF dataset open
231for writing. You cannot rename a dimension to have the same name as
232another dimension.
233
234For netCDF classic and 64-bit offset files, if the new name is longer
235than the old name, the netCDF dataset must be in define mode.
236
237For netCDF-4 files the dataset is switched to define more for the
238rename, regardless of the name length.
239
240\param ncid NetCDF or group ID, from a previous call to nc_open(),
241nc_create(), nc_def_grp(), or associated inquiry functions such as
242nc_inq_ncid().
243
244\param dimid Dimension ID, from a previous call to nc_inq_dimid() or
245nc_def_dim().
246
247\param name New name for dimension. Must be a null-terminated string
248with length less than NC_MAX_NAME.
249
250\returns ::NC_NOERR      No error.
251\returns ::NC_EBADID     Not a valid ID.
252\returns ::NC_EBADDIM    Invalid dimension ID or name.
253\returns ::NC_ENAMEINUSE String match to name in use
254\returns ::NC_ENOMEM     Memory allocation (malloc) failure
255\returns ::NC_EPERM      Write to read only
256\section nc_rename_dim_example Example
257
258Here is an example using nc_rename_dim to rename the dimension lat to
259latitude in an existing netCDF dataset named foo.nc:
260
261\code
262     #include <netcdf.h>
263        ...
264     int status, ncid, latid;
265        ...
266     status = nc_open("foo.nc", NC_WRITE, &ncid);
267     if (status != NC_NOERR) handle_error(status);
268        ...
269     status = nc_redef(ncid);
270     if (status != NC_NOERR) handle_error(status);
271     status = nc_inq_dimid(ncid, "lat", &latid);
272     if (status != NC_NOERR) handle_error(status);
273     status = nc_rename_dim(ncid, latid, "latitude");
274     if (status != NC_NOERR) handle_error(status);
275     status = nc_enddef(ncid);
276     if (status != NC_NOERR) handle_error(status);
277\endcode
278 */
279int
280nc_rename_dim(int ncid, int dimid, const char *name)
281{
282    NCncp;
283    int stat = NC_check_id(ncid, &ncp);
284    if(stat != NC_NOERR) return stat;
285    TRACE(nc_rename_dim);
286    return ncp->dispatch->rename_dim(ncid,dimid,name);
287}
288
289/*!
290Find the number of dimensions.
291
292In a classic model netCDF file, this function returns the number of
293defined dimensions. In a netCDF-4/HDF5 file, this function returns the
294number of dimensions available in the group specified by ncid, which
295may be less than the total number of dimensions in a file. In a
296netCDF-4/HDF5 file, dimensions are in all sub-groups, sub-sub-groups,
297etc.
298
299\param ncid NetCDF or group ID, from a previous call to nc_open(),
300nc_create(), nc_def_grp(), or associated inquiry functions such as
301nc_inq_ncid().
302
303\param ndimsp Pointer where number of dimensions will be
304written. Ignored if NULL.
305
306\returns ::NC_NOERR  No error.
307\returns ::NC_EBADID Not a valid ID.
308
309 */
310int
311nc_inq_ndims(int ncid, int *ndimsp)
312{
313    NCncp;
314    int stat = NC_check_id(ncid, &ncp);
315    if(stat != NC_NOERR) return stat;
316    if(ndimsp == NULL) return NC_NOERR;
317    TRACE(nc_inq_ndims);
318    return ncp->dispatch->inq(ncid,ndimsp,NULL,NULL,NULL);
319}
320
321/*!
322Find the ID of the unlimited dimension.
323
324This function finds the ID of the unlimited dimension. For
325netCDF-4/HDF5 files (which may have more than one unlimited
326dimension), the ID of the first unlimited dimesnion is returned. For
327these files, nc_inq_unlimdims() will return all the unlimited dimension IDs.
328
329\param ncid NetCDF or group ID, from a previous call to nc_open(),
330nc_create(), nc_def_grp(), or associated inquiry functions such as
331nc_inq_ncid().
332
333\param unlimdimidp Pointer where unlimited dimension ID will be
334stored. If there is no unlimited dimension, -1 will be stored
335here. Ignored if NULL.
336
337\returns ::NC_NOERR  No error.
338\returns ::NC_EBADID Not a valid ID.
339
340 */
341int
342nc_inq_unlimdim(int ncid, int *unlimdimidp)
343{
344    NCncp;
345    int stat = NC_check_id(ncid, &ncp);
346    if(stat != NC_NOERR) return stat;
347    TRACE(nc_inq_unlimdim);
348    return ncp->dispatch->inq_unlimdim(ncid,unlimdimidp);
349}
350
351/*!
352Find out the name of a dimension.
353
354\param ncid NetCDF or group ID, from a previous call to nc_open(),
355nc_create(), nc_def_grp(), or associated inquiry functions such as
356nc_inq_ncid().
357
358\param dimid Dimension ID, from a previous call to nc_inq_dimid() or
359nc_def_dim().
360
361\param name Returned dimension name. The caller must allocate space
362for the returned name. The maximum possible length, in characters, of
363a dimension name is given by the predefined constant
364NC_MAX_NAME. (This doesn't include the null terminator, so declare
365your array to be size NC_MAX_NAME+1). The returned character array
366will be null-terminated. Ignored if NULL.
367
368\returns ::NC_NOERR   No error.
369\returns ::NC_EBADID  Not a valid ID.
370\returns ::NC_EBADDIM Invalid dimension ID or name.
371
372\section nc_inq_dim_example2 Example
373
374Here is an example using nc_inq_dim() to determine the length of a
375dimension named lat, and the name and current maximum length of the
376unlimited dimension for an existing netCDF dataset named foo.nc:
377
378\code
379     #include <netcdf.h>
380        ...
381     int status, ncid, latid, recid;
382     size_t latlength, recs;
383     char recname[NC_MAX_NAME+1];
384        ...
385     status = nc_open("foo.nc", NC_NOWRITE, &ncid);
386     if (status != NC_NOERR) handle_error(status);
387     status = nc_inq_unlimdim(ncid, &recid);
388     if (status != NC_NOERR) handle_error(status);
389        ...
390     status = nc_inq_dimid(ncid, "lat", &latid);
391     if (status != NC_NOERR) handle_error(status);
392     status = nc_inq_dimlen(ncid, latid, &latlength);
393     if (status != NC_NOERR) handle_error(status);
394
395     status = nc_inq_dim(ncid, recid, recname, &recs);
396     if (status != NC_NOERR) handle_error(status);
397\endcode
398
399 */
400int
401nc_inq_dimname(int ncid, int dimid, char *name)
402{
403    NCncp;
404    int stat = NC_check_id(ncid, &ncp);
405    if(stat != NC_NOERR) return stat;
406    if(name == NULL) return NC_NOERR;
407    TRACE(nc_inq_dimname);
408    return ncp->dispatch->inq_dim(ncid,dimid,name,NULL);
409}
410
411/*!
412Find the length of a dimension.
413
414The length for the unlimited dimension, if any, is the number of
415records written so far.
416
417\param ncid NetCDF or group ID, from a previous call to nc_open(),
418nc_create(), nc_def_grp(), or associated inquiry functions such as
419nc_inq_ncid().
420
421\param dimid Dimension ID, from a previous call to nc_inq_dimid() or
422nc_def_dim().
423
424\param lenp Pointer where the length will be stored.
425
426\returns ::NC_NOERR   No error.
427\returns ::NC_EBADID  Not a valid ID.
428\returns ::NC_EBADDIM Invalid dimension ID or name.
429
430\section nc_inq_dim_example3 Example
431
432Here is an example using nc_inq_dim() to determine the length of a
433dimension named lat, and the name and current maximum length of the
434unlimited dimension for an existing netCDF dataset named foo.nc:
435
436\code
437     #include <netcdf.h>
438        ...
439     int status, ncid, latid, recid;
440     size_t latlength, recs;
441     char recname[NC_MAX_NAME+1];
442        ...
443     status = nc_open("foo.nc", NC_NOWRITE, &ncid);
444     if (status != NC_NOERR) handle_error(status);
445     status = nc_inq_unlimdim(ncid, &recid);
446     if (status != NC_NOERR) handle_error(status);
447        ...
448     status = nc_inq_dimid(ncid, "lat", &latid);
449     if (status != NC_NOERR) handle_error(status);
450     status = nc_inq_dimlen(ncid, latid, &latlength);
451     if (status != NC_NOERR) handle_error(status);
452
453     status = nc_inq_dim(ncid, recid, recname, &recs);
454     if (status != NC_NOERR) handle_error(status);
455\endcode
456 */
457int
458nc_inq_dimlen(int ncid, int dimid, size_t *lenp)
459{
460    NCncp;
461    int stat = NC_check_id(ncid, &ncp);
462    if(stat != NC_NOERR) return stat;
463    if(lenp == NULL) return NC_NOERR;
464    TRACE(nc_inq_dimlen);
465    return ncp->dispatch->inq_dim(ncid,dimid,NULL,lenp);
466}
467
468/*! \} */  /* End of named group ...*/
469
470/*! \} */ /* End of defgroup. */


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed