Initial copy of files into NUG directory.

This commit is contained in:
Ward Fisher 2020-02-06 14:23:46 -07:00
parent 3aaf092b59
commit e6708aaa82
30 changed files with 11484 additions and 0 deletions

259
NUG/DAP4.dox Normal file
View File

@ -0,0 +1,259 @@
/*!
\page dap4 DAP4 Protocol Support
<!-- Note that this file has the .dox extension, but is mostly markdown -->
<!-- Begin MarkDown -->
\tableofcontents
# DAP4 Introduction {#dap4_introduction}
Beginning with netCDF version 4.5.0, optional support is provided for
accessing data from servers supporting the DAP4 protocol.
DAP4 support is enabled if the _--enable-dap_ option
is used with './configure'. If DAP4 support is enabled, then
a usable version of _libcurl_ must be specified
using the _LDFLAGS_ environment variable (similar to the way
that the _HDF5_ libraries are referenced).
Refer to the installation manual for details.
By default DAP4 support is enabled if _libcurl_ is found.
DAP4 support can be disabled using the _--disable-dap_.
DAP4 uses a data model that is, by design, similar to,
but -- for historical reasons -- not identical with,
the netCDF-Enhanced (aka netcdf-4) model.
Generically, the DAP4 data model is encoded in XML document
called a DMR.
For detailed information about the DAP4 DMR, refer to
the DAP4 specification Volume 1:
http://docs.opendap.org/index.php/DAP4:_Specification_Volume_1
# Accessing Data Using the DAP4 Prototocol {#dap4_accessing_data}
In order to access a DAP4 data source through the netCDF API, the
file name normally used is replaced with a URL with a specific
format. The URL is composed of three parts.
- URL - this is a standard form URL with specific markers to indicate that
it refers to a DAP4 encoded dataset. The markers are of the form
"dap4", "mode=dap4", or "/thredds/dap4". The following
examples show how they are specified. Note that the "/thredds/dap4"
case will only work when accessing a Thredds-based server.
+ [dap4]http://remotetest.unidata.ucar.edu/d4ts/test.01
+ [mode=dap4]http://remotetest.unidata.ucar.edu/d4ts/test.01
+ http://remotetest.unidata.ucar.edu/d4ts/test.01#dap4
+ http://remotetest.unidata.ucar.edu/d4ts/test.01#mode=dap4
+ http://thredds.ucar.edu/thredds/dap4/...
- Constraints - these are suffixed to the URL and take the form
“?dap4.ce=\<expression\>”. The form of the constraint expression
is somewhat complicated, and the specification should be consulted.
- Client parameters - these may be specified in either of
two ways. The older, deprecated form prefixes text to the
front of the url and is of the the general form [\<name>]
or [\<name>=value]. Examples include [show=fetch] or [noprefetch].
The newer, preferred form prefixes the
parameters to the end of the url using the semi-standard '#'
format: e.g. http://....#show=fetch&noprefetch.
It is possible to see what the translation does to a particular DAP4
data source in two steps. First, one can examine the DMR
source through a web browser and then second, one can examine
the translation using the "ncdump -h" command to see the
corresponding netCDF-4 representation.
For example, if a web browser is given the following (fictional) URL,
it will return the DMR for the specified dataset (in XML format).
\code
http://remotetest.unidata.ucar.edu/d4ts/test.01.dmr.xml#dap4
\endcode
By using the following ncdump command, it is possible to see the
equivalent netCDF-4 translation.
\code
ncdump -h '[dap4]http://remotetest.unidata.ucar.edu/d4ts/test.01'
\endcode
# Defined Client Parameters {#dap4_defined_params}
Currently, a limited set of client parameters is
recognized. Parameters not listed here are
ignored, but no error is signalled.
Parameter Name Legal Values Semantics
- "log" | "log=<file>" - Turn on logging and send the log output to
the specified file. If no file is specified, then output is sent to standard
error.
- "show=fetch" - This parameter causes the netCDF code to log a copy
of the complete url for every HTTP get request. If logging is
enabled, then this can be helpful in checking to see the access
behavior of the netCDF code.
- "translate=nc4" - This parameter causes the netCDF code to look
for specially named elements in the DMR XML in order to
achieve a better translation of the DAP4 meta-data to NetCDF enhanced
metadata.
- "opaquesize=<integer>" - This parameter causes the netCDF code to
convert DAP4 variable size OPAQUE objects to netcdf-4 fixed size
objects and forces all of them to be of the size specified.
- "fillmismatch" - Unfortunately, a number of servers sometimes
fail to make sure that the type of the "_FillValue" attribute of a variable
is the same as the type of the containing variable. Setting this tag
caused the netcdf translation to attempt to fix this mismatch. If not set,
then an error will occur.
# Notes on Debugging DAP4 Access {#dap4_debug}
The DAP4 support has a logging facility.
Turning on this logging can
sometimes give important information. Logging can be enabled by
using the client parameter "log" or "log=filename",
where the first case will send log output to standard error and the
second will send log output to the specified file.
Users should also be aware that if one is
accessing data over an NFS mount, one may see some .nfsxxxxx files;
those can be ignored.
## HTTP Configuration. {#dap4_http2_config}
Limited support for configuring the http connection is provided via
parameters in the “.daprc” configuration file (aka ".dodsrc").
The relevant .daprc file is
located by first looking in the current working directory, and if not
found, then looking in the directory specified by the “$HOME”
environment variable.
Entries in the .daprc file are of the form:
````
['['<url>']']<key>=<value>
````
That is, it consists of a key name and value pair and optionally
preceded by a url enclosed in square brackets.
For given KEY and URL strings, the value chosen is as follows:
If URL is null, then look for the .daprc entry that has no url prefix
and whose key is same as the KEY for which we are looking.
If the URL is not null, then look for all the .daprc entries that
have a url, URL1, say, and for which URL1 has the same host and port
as URL. All parts of the url's except host and port are ignored.
For example, if URL = http//x.y/a, then it will match
entries of the form
_[http//x.y/a]KEY=VALUE_ or _[http//x.y/b]KEY=VALUE_.
It will not match an entry of the form _[http//x.y:8080]KEY=VALUE
because the second has a port number (8080) different than the URL.
Finally from the set so constructed, choose the first matching entry.
Currently, the supported set of keys (with descriptions) are as
follows.
-# HTTP.VERBOSE
Type: boolean ("1"/"0")
Description: Produce verbose output, especially using SSL.
Related CURL Flags: CURLOPT_VERBOSE
-# HTTP.DEFLATE
Type: boolean ("1"/"0")
Description: Allow use of compression by the server.
Related CURL Flags: CURLOPT_ENCODING
-# HTTP.COOKIEJAR
Type: String representing file path
Description: Specify the name of file into which to store cookies. Defaults to in-memory storage.
Related CURL Flags:CURLOPT_COOKIEJAR
-# HTTP.CREDENTIALS.USER
Type: String representing user name
Description: Specify the user name for Digest and Basic authentication.
Related CURL Flags:
-# HTTP.CREDENTIALS.PASSWORD
Type: String representing password
Type: boolean ("1"/"0")
Description: Specify the password for Digest and Basic authentication.
Related CURL Flags:
-# HTTP.SSL.CERTIFICATE
Type: String representing file path
Description: Path to a file containing a PEM cerficate.
Related CURL Flags: CURLOPT_CERT
-# HTTP.SSL.KEY
Type: String representing file path
Description: Same as HTTP.SSL.CERTIFICATE, and should usually have the same value.
Related CURL Flags: CURLOPT_SSLKEY
-# HTTP.SSL.KEYPASSWORD
Type: String representing password
Description: Password for accessing the HTTP.SSL.KEY/HTTP.SSL.CERTIFICATE
Related CURL Flags: CURLOPT_KEYPASSWORD
-# HTTP.SSL.CAPATH
Type: String representing directory
Description: Path to a directory containing trusted certificates for validating server certificates.
Related CURL Flags: CURLOPT_CAPATH
-# HTTP.SSL.VALIDATE
Type: boolean ("1"/"0")
Description: Cause the client to verify the server's presented certificate.
Related CURL Flags: CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST
-# HTTP.TIMEOUT
Type: String ("dddddd")
Description: Specify the maximum time in seconds that you allow the http transfer operation to take.
Related CURL Flags: CURLOPT_TIMEOUT, CURLOPT_NOSIGNAL, CURLOPT_CONNECTIONTIMEOUT
-# HTTP.PROXY_SERVER
Type: String representing url to access the proxy: (e.g.http://[username:password@]host[:port])
Description: Specify the needed information for accessing a proxy.
Related CURL Flags: CURLOPT_PROXY, CURLOPT_PROXYHOST, CURLOPT_PROXYUSERPWD
-# HTTP.READ.BUFFERSIZE
Type: String ("dddddd")
Description: Specify the the internal buffer size for curl reads.
Related CURL Flags: CURLOPT_BUFFERSIZE, CURL_MAX_WRITE_SIZE (16kB),
CURL_MAX_READ_SIZE (512kB).
-# HTTP.KEEPALIVE
Type: String ("on|n/m")
Description: Specify that TCP KEEPALIVE should be enabled and that the associated idle wait time is n and that the associated repeat interval is m. If the value is of the form is the string "on", then turn on keepalive, but do not set idle or interval.
Related CURL Flags: CURLOPT_TCP_KEEPALIVE, CURLOPT_TCP_KEEPIDLE,
CURLOPT_TCP_KEEPINTVL.
-# HTTP.CONNECTIONTIMEOUT
Type: String ("dddddd")
Description: Specify the maximum time in seconds that you allow the http connection to complete.
Related CURL Flags: CURLOPT_TIMEOUT, CURLOPT_NOSIGNAL
The related curl flags line indicates the curl flags modified by this
key. See the libcurl documentation of the _curl_easy_setopt()_ function
for more detail (http://curl.haxx.se/libcurl/c/curl_easy_setopt.html).
For servers that require client authentication, as a rule, the following
.daprc entries should be specified.
````
HTTP.SSL.VALIDATE
HTTP.COOKIEJAR
HTTP.SSL.CERTIFICATE
HTTP.SSL.KEY
HTTP.SSL.CAPATH
````
Additionally, the _HTTP.SSL.CERTIFICATE_ and _HTTP.SSL.KEY_
entries should have same value, which is the file path for a
certificate. The HTTP.SSL.CAPATH entry should
be the path to a directory containing validation "certificates".
# Point of Contact {#dap4_poc}
__Author__: Dennis Heimbigner<br>
__Email__: dmh at ucar dot edu<br>
__Initial Version__: 6/5/2017<br>
__Last Revised__: 11/7/2018
*/

2489
NUG/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

730
NUG/OPeNDAP.dox Normal file
View File

@ -0,0 +1,730 @@
/*!
\page dap2 DAP2 Support
\tableofcontents
\section dap_introduction DAP2 (OPeNDAP) Introduction
Beginning with netCDF version 4.1, optional support is provided for
accessing data through OPeNDAP servers using the DAP protocol.
Currently, only DAP protocol version 2 is supported; DAP protocol
version 4 support is under development.
DAP support is automatically enabled if a usable curl library can be
set using the LDFLAGS environment variable (similar to the way
that the HDF5 libraries are referenced).
DAP support can forcibly be enabled or disabled using the --enable-dap
flag or the --disable-dap flag, respectively. If enabled,
then DAP2 support requires access to the curl library.
Refer to the installation manual for details
DAP uses a data model that is different from that supported by netCDF,
either classic or enhanced. Generically, the DAP data model is encoded
textually in a DDS (Dataset Descriptor Structure). There is a second
data model for DAP attributes, which is encoded textually in a DAS
(Dataset Attribute Structure). For detailed information about the DAP
DDS and DAS, refer to the OPeNDAP web site http://opendap.org.
\subsection dap_dap_information OPeNDAP Documentation
See the following pages for more information.
- \subpage dap_accessing_data
- <a href="auth.md">netCDF Authorization Support</a>
- \subpage dap_to_netcdf
- \subpage dap2_reserved_keywords
- \subpage var_dim_trans
- \subpage var_name_trans
\section dap_accessing_data Accessing OPeNDAP Data
In order to access an OPeNDAP data source through the netCDF API, the
file name normally used is replaced with a URL with a specific
format. The URL is composed of three parts.
- URL - this is a standard form URL such as
http://remotetest.unidata.ucar.edu/dts/test.01
- Constraints - these are suffixed to the URL and take the form
“?\<projections>&\<selections>”. The meaning of the terms projection
and selection is somewhat complicated; and the OPeNDAP web site,
http://www.opendap.org , should be consulted. The interaction of DAP
constraints with netCDF is complex and at the moment requires an
understanding of how DAP is translated to netCDF.
- Client parameters - these may be specified in either of
two ways. The older, deprecated form prefixes text to the
front of the url and is of the the general form [\<name>]
or [\<name>=value]. Examples include [show=fetch] and
[noprefetch]. The newer, preferred form prefixes the
parameters to the end of the url using the semi-standard '#'
format: e.g. http://....#show=fetch&noprefetch.
It is possible to see what the translation does to a particular DAP
data source in either of two ways. First, one can examine the DDS
source through a web browser and then examine the translation using
the ncdump -h command to see the netCDF Classic translation. The
ncdump output will actually be the union of the DDS with the DAS, so
to see the complete translation, it is necessary to view both.
For example, if a web browser is given the following, the first URL
will return the DDS for the specified dataset, and the second URL will
return the DAS for the specified dataset.
\code
http://remotetest.unidata.ucar.edu/dts/test.01.dds
http://remotetest.unidata.ucar.edu/dts/test.01.das
\endcode
Then by using the following ncdump command, it is possible to see the
equivalent netCDF Classic translation.
\code
ncdump -h http://remotetest.unidata.ucar.edu/dts/test.01
\endcode
The DDS output from the web server should look like this.
\code
Dataset {
Byte b;
Int32 i32;
UInt32 ui32;
Int16 i16;
UInt16 ui16;
Float32 f32;
Float64 f64;
String s;
Url u;
} SimpleTypes;
\endcode
The DAS output from the web server should look like this.
\code
Attributes {
Facility {
String PrincipleInvestigator ``Mark Abbott'', ``Ph.D'';
String DataCenter ``COAS Environmental Computer Facility'';
String DrifterType ``MetOcean WOCE/OCM'';
}
b {
String Description ``A test byte'';
String units ``unknown'';
}
i32 {
String Description ``A 32 bit test server int'';
String units ``unknown'';
}
}
\endcode
The output from ncdump should look like this.
\code
netcdf test {
dimensions:
stringdim64 = 64 ;
variables:
byte b ;
b:Description = "A test byte" ;
b:units = "unknown" ;
int i32 ;
i32:Description = "A 32 bit test server int" ;
i32:units = "unknown" ;
int ui32 ;
short i16 ;
short ui16 ;
float f32 ;
double f64 ;
char s(stringdim64) ;
char u(stringdim64) ;
}
\endcode
Note that the fields of type String and type URL have suddenly
acquired a dimension. This is because strings are translated to arrays
of char, which requires adding an extra dimension. The size of the
dimension is determined in a variety of ways and can be specified. It
defaults to 64 and when read, the underlying string is either padded
or truncated to that length.
Also note that the Facility attributes do not appear in the
translation because they are neither global nor associated with a
variable in the DDS.
Alternately, one can get the text of the DDS as a global attribute by
using the client parameters mechanism . In this case, the parameter
“show=dds” can be used, and the data retrieved using
the following command
\code
ncdump -h http://remotetest.unidata.ucar.edu/dts/test.01.dds#show=dds
\endcode
The ncdump -h command will then show both the translation and the
original DDS. In the above example, the DDS would appear as the global
attribute “_DDS” as follows.
\code
netcdf test {
...
variables:
:_DDS = "Dataset { Byte b; Int32 i32; UInt32 ui32; Int16 i16;
UInt16 ui16; Float32 f32; Float64 f64;
Strings; Url u; } SimpleTypes;"
byte b ;
...
}
\endcode
\section dap_to_netcdf DAP to NetCDF Translation Rules
Currently only one translation available: DAP 2 Protocol to netCDF-3.
There used to be a DAP 2 Protocol to netCDF-4 translation
but that has been removed until the DAP4 protocol is available.
\subsection nc3_trans_rules netCDF-3 Translation Rules
The current default translation code translates the OPeNDAP protocol
to netCDF-3 (classic). This netCDF-3 translation converts an OPeNDAP
DAP protocol version 2 DDS to netCDF-3 and is designed to mimic as
closely as possible the translation provided by the libnc-dap
system, except that some errors in that older translation have
been fixed.
For illustrative purposes, the following example will be used.
\code
Dataset {
Int32 f1;
Structure {
Int32 f11;
Structure {
Int32 f1[3];
Int32 f2;
} FS2[2];
} S1;
Structure {
Grid {
Array:
Float32 temp[lat=2][lon=2];
Maps:
Int32 lat[lat=2];
Int32 lon[lon=2];
} G1;
} S2;
Grid {
Array:
Float32 G2[lat=2][lon=2];
Maps:
Int32 lat[2];
Int32 lon[2];
} G2;
Int32 lat[lat=2];
Int32 lon[lon=2];
} D1;
\endcode
\subsection var_def Variable Definition
The set of netCDF variables is derived from the fields with primitive
base types as they occur in Sequences, Grids, and Structures. The
field names are modified to be fully qualified initially. For the
above, the set of variables are as follows. The coordinate variables
within grids are left out in order to mimic the behavior of libnc-dap.
\code
f1
S1.f11
S1.FS2.f1
S1.FS2.f2
S2.G1.temp
S2.G2.G2
lat
lon
\endcode
\section dap2_reserved_keywords DAP2 Reserved Keywords
In the OPeNDAP DAP2 protocol, there are a number of reserved keywords. These keywords are case insensitive and if you use one as a netCDF variable name, you may encounter odd behavior such as case changes (depending on the client DDS/DAS parser). The list of reserved keywords as used by the netCDF-C library parser are as follows:
- alias
- array
- attributes
- byte
- dataset
- error
- float32
- float64
- grid
- int16
- int32
- maps
- sequence
- string
- structure
- uint16
- uint32
- url
- code
- message
- program_type
- program
\section var_dim_trans Variable Dimension Translation
A variable's rank is determined from three sources.
- The variable has the dimensions associated with the field it
represents (e.g. S1.FS2.f1[3] in the above example).
- The variable inherits the dimensions associated with any containing
structure that has a rank greater than zero. These dimensions precede
those of case 1. Thus, we have in our example, f1[2][3], where the
first dimension comes from the containing Structure FS2[2].
- The variable's set of dimensions are altered if any of its
containers is a DAP DDS Sequence. This is discussed more fully below.
If the type of the netCDF variable is char, then an extra string
dimension is added as the last dimension.
\subsection dim_trans Dimension translation
For dimensions, the rules are as follows.
Fields in dimensioned structures inherit the dimension of the
structure; thus the above list would have the following dimensioned
variables.
\code
S1.FS2.f1 -> S1.FS2.f1[2][3]
S1.FS2.f2 -> S1.FS2.f2[2]
S2.G1.temp -> S2.G1.temp[lat=2][lon=2]
S2.G1.lat -> S2.G1.lat[lat=2]
S2.G1.lon -> S2.G1.lon[lon=2]
S2.G2.G2 -> S2.G2.lon[lat=2][lon=2]
S2.G2.lat -> S2.G2.lat[lat=2]
S2.G2.lon -> S2.G2.lon[lon=2]
lat -> lat[lat=2]
lon -> lon[lon=2]
\endcode
Collect all of the dimension specifications from the DDS, both named
and anonymous (unnamed) For each unique anonymous dimension with value
NN create a netCDF dimension of the form "XX_<i>=NN", where XX is the
fully qualified name of the variable and i is the i'th (inherited)
dimension of the array where the anonymous dimension occurs. For our
example, this would create the following dimensions.
\code
S1.FS2.f1_0 = 2 ;
S1.FS2.f1_1 = 3 ;
S1.FS2.f2_0 = 2 ;
S2.G2.lat_0 = 2 ;
S2.G2.lon_0 = 2 ;
\endcode
If however, the anonymous dimension is the single dimension of a MAP
vector in a Grid then the dimension is given the same name as the map
vector This leads to the following.
\code
S2.G2.lat_0 -> S2.G2.lat
S2.G2.lon_0 -> S2.G2.lon
\endcode
For each unique named dimension "<name>=NN", create a netCDF dimension
of the form "<name>=NN", where name has the qualifications removed. If
this leads to duplicates (i.e. same name and same value), then the
duplicates are ignored. This produces the following.
\code
S2.G2.lat -> lat
S2.G2.lon -> lon
\endcode
Note that this produces duplicates that will be ignored later.
At this point the only dimensions left to process should be named
dimensions with the same name as some dimension from step number 3,
but with a different value. For those dimensions create a dimension of
the form "<name>M=NN" where M is a counter starting at 1. The example
has no instances of this.
Finally and if needed, define a single UNLIMITED dimension named
"unlimited" with value zero. Unlimited will be used to handle certain
kinds of DAP sequences (see below).
This leads to the following set of dimensions.
\code
dimensions:
unlimited = UNLIMITED;
lat = 2 ;
lon = 2 ;
S1.FS2.f1_0 = 2 ;
S1.FS2.f1_1 = 3 ;
S1.FS2.f2_0 = 2 ;
\endcode
\section var_name_trans Variable Name Translation
The steps for variable name translation are as follows.
Take the set of variables captured above. Thus for the above DDS, the
following fields would be collected.
\code
f1
S1.f11
S1.FS2.f1
S1.FS2.f2
S2.G1.temp
S2.G2.G2
lat
lon
\endcode
All grid array variables are renamed to be the same as the containing
grid and the grid prefix is removed. In the above DDS, this results in
the following changes.
\code
G1.temp -> G1
G2.G2 -> G2
\endcode
It is important to note that this process could produce duplicate
variables (i.e. with the same name); in that case they are all assumed
to have the same content and the duplicates are ignored. If it turns
out that the duplicates have different content, then the translation
will not detect this. YOU HAVE BEEN WARNED.
The final netCDF-3 schema (minus attributes) is then as follows.
\code
netcdf t {
dimensions:
unlimited = UNLIMITED ;
lat = 2 ;
lon = 2 ;
S1.FS2.f1_0 = 2 ;
S1.FS2.f1_1 = 3 ;
S1.FS2.f2_0 = 2 ;
variables:
int f1 ;
int lat(lat) ;
int lon(lon) ;
int S1.f11 ;
int S1.FS2.f1(S1.FS2.f1_0, S1.FS2.f1_1) ;
int S1.FS2.f2(S1_FS2_f2_0) ;
float S2.G1(lat, lon) ;
float G2(lat, lon) ;
}
\endcode
In actuality, the unlimited dimension is dropped because it is unused.
There are differences with the original libnc-dap here because
libnc-dap technically was incorrect. The original would have said
this, for example.
\code
int S1.FS2.f1(lat, lat) ;
\endcode
Note that this is incorrect because it dimensions S1.FS2.f1(2,2)
rather than S1.FS2.f1(2,3).
\subsection dap_translation Translating DAP DDS Sequences
Any variable (as determined above) that is contained directly or
indirectly by a Sequence is subject to revision of its rank using the
following rules.
Let the variable be contained in Sequence Q1, where Q1 is the
innermost containing sequence. If Q1 is itself contained (directly or
indirectly) in a sequence, or Q1 is contained (again directly or
indirectly) in a structure that has rank greater than 0, then the
variable will have an initial UNLIMITED dimension. Further, all
dimensions coming from "above" and including (in the containment
sense) the innermost Sequence, Q1, will be removed and replaced by
that single UNLIMITED dimension. The size associated with that
UNLIMITED is zero, which means that its contents are inaccessible
through the netCDF-3 API. Again, this differs from libnc-dap, which
leaves out such variables. Again, however, this difference is backward
compatible.
If the variable is contained in a single Sequence (i.e. not nested)
and all containing structures have rank 0, then the variable will have
an initial dimension whose size is the record count for that
Sequence. The name of the new dimension will be the name of the
Sequence.
Consider this example.
\code
Dataset {
Structure {
Sequence {
Int32 f1[3];
Int32 f2;
} SQ1;
} S1[2];
Sequence {
Structure {
Int32 x1[7];
} S2[5];
} Q2;
} D;
\endcode
The corresponding netCDF-3 translation is pretty much as follows (the
value for dimension Q2 may differ).
\code
dimensions:
unlimited = UNLIMITED ; // (0 currently)
S1.SQ1.f1_0 = 2 ;
S1.SQ1.f1_1 = 3 ;
S1.SQ1.f2_0 = 2 ;
Q2.S2.x1_0 = 5 ;
Q2.S2.x1_1 = 7 ;
Q2 = 5 ;
variables:
int S1.SQ1.f1(unlimited, S1.SQ1.f1_1) ;
int S1.SQ1.f2(unlimited) ;
int Q2.S2.x1(Q2, Q2.S2.x1_0, Q2.S2.x1_1) ;
\endcode
Note that for example S1.SQ1.f1_0 is not actually used because it has
been folded into the unlimited dimension.
Note that for sequences without a leading unlimited dimension, there
is a performance cost because the translation code has to walk the
data to determine how many records are associated with the
sequence. Since libnc-dap did essentially the same thing, it can be
assumed that the cost is not prohibitive.
\section dap_caching Caching
In an effort to provide better performance for some access patterns,
client-side caching of data is available. The default is no caching,
but it may be enabled by prefixing the URL with the parameter "cache".
Caching operates basically as follows.
When a URL is first accessed using nc_open(), netCDF automatically
does a pre-fetch of selected variables. These include all variables
smaller than a specified (and user definable) size. This allows, for
example, quick access to coordinate variables. This can be suppressed
with the parameter "noprefetch".
Whenever a request is made using some variant of the nc_get_var() API
procedures, the complete variable is fetched and stored in the cache
as a new cache entry. Subsequence requests for any part of that
variable will access the cache entry to obtain the data.
The cache may become too full, either because there are too many
entries or because it is taking up too much disk space. In this case
cache entries are purged until the cache size limits are reached. The
cache purge algorithm is LRU (least recently used) so that variables
that are repeatedly referenced will tend to stay in the cache.
The cache is completely purged when nc_close() is invoked.
In order to decide if you should enable caching, you will need to have
some understanding of the access patterns of your program.
The ncdump program always dumps one or more whole variables so it
turns on caching.
If your program accesses only parts of a number of variables, then
caching should probably not be used since fetching whole variables
will probably slow down your program for no purpose.
Unfortunately, caching is currently an all or nothing proposition, so
for more complex access patterns, the decision to cache or not may not
have an obvious answer. Probably a good rule of thumb is to avoid
caching initially and later turn it on to see its effect on
performance.
\section dap_defined_params Defined Client Parameters
Currently, a limited set of client parameters is
recognized. Parameters not listed here are ignored, but no error is
signalled. All names are case insensitive.
Parameter Name Legal Values Semantics
- "log" | "log=<file>" - Turn on logging and send the log output to
the specified file. If no file is specified, then output is sent to standard
error.
- "show=... das|dds|url" - This causes information to appear as
specific global attributes. The currently recognized tags are "dds"
to display the underlying DDS, "das" similarly, and "url" to display
the url used to retrieve the data. This parameter may be specified
multiple times (e.g. “show=dds&show=url”).
- "show=fetch" - This parameter causes the netCDF code to log a copy
of the complete url for every HTTP get request. If logging is
enabled, then this can be helpful in checking to see the access
behavior of the netCDF code.
- "stringlength=NN" - Specify the default string length to use for
string dimensions. The default is 64. The name "maxstrlen" is an
alias for "stringlength".
- "stringlength_<var>=NN" - Specify the default string length to use
for a string dimension for the specified variable. The default is
64. The name "maxstrlen_<var>" is an alias for "stringlength_<var>".
- "cache" - This enables caching.
- "nocache" - This disbles caching.
- "cachelimit=NN" - Specify the maximum amount of space allowed for
the cache.
- "cachecount=NN" - Specify the maximum number of entries in the
cache.
- "prefetch" - This enables prefetch of small variables (default).
- "noprefetch" - This disables prefetch of small variables.
- "fillmismatch" - This enables _FillValue/Variable type mismatch.
- "nofillmismatch" - This disables _FillValue/Variable type mismatch (default).
\section dap_debug Notes on Debugging OPeNDAP Access
The OPeNDAP support makes use of the logging facility of the
underlying oc system (see http://www.opendap.org/oc).
Note that this is currently separate from the
existing netCDF logging facility. Turning on this logging can
sometimes give important information. Logging can be enabled by
using the client parameter "log" or "log=filename",
where the first case will send log output to standard error and the
second will send log output to the specified file.
Users should also be aware that if one is
accessing data over an NFS mount, one may see some .nfsxxxxx files;
those can be ignored.
\subsection http_config HTTP Configuration.
Limited support for configuring the http connection is provided via
parameters in the “.dodsrc” configuration file. The relevant .dodsrc file is
located by first looking in the current working directory, and if not
found, then looking in the directory specified by the “$HOME”
environment variable.
Entries in the .dodsrc file are of the form:
\code
['['<url>']']<key>=<value>
\endcode
That is, it consists of a key name and value pair and optionally
preceded by a url enclosed in square brackets.
For given KEY and URL strings, the value chosen is as follows:
If URL is null, then look for the .dodsrc entry that has no url prefix
and whose key is same as the KEY for which we are looking.
If the URL is not null, then look for all the .dodsrc entries that
have a url, URL1, say, and for which URL1 is a prefix (in the string
sense) of URL. For example, if URL = http//x.y/a, then it will match
entries of the form
\code
1. [http//x.y/a]KEY=VALUE
2. [http//x.y/a/b]KEY=VALUE
\endcode
It will not match an entry of the form
\code
[http//x.y/b]KEY=VALUE
\endcode
because “http://x.y/b” is not a string prefix of
“http://x.y/a”. Finally from the set so constructed, choose the entry
with the longest url prefix: “http//x.y/a/b]KEY=VALUE” in this case.
Currently, the supported set of keys (with descriptions) are as
follows.
<pre>
HTTP.VERBOSE
Type: boolean ("1"/"0")
Description: Produce verbose output, especially using SSL.
Related CURL Flags: CURLOPT_VERBOSE
HTTP.DEFLATE
Type: boolean ("1"/"0")
Description: Allow use of compression by the server.
Related CURL Flags: CURLOPT_ENCODING
HTTP.COOKIEJAR
Type: String representing file path
Description: Specify the name of file into which to store cookies. Defaults to in-memory storage.
Related CURL Flags:CURLOPT_COOKIEJAR
HTTP.CREDENTIALS.USER
Type: String representing user name
Description: Specify the user name for Digest and Basic authentication.
Related CURL Flags:
HTTP.CREDENTIALS.PASSWORD
Type: String representing password
Type: boolean ("1"/"0")
Description: Specify the password for Digest and Basic authentication.
Related CURL Flags:
HTTP.SSL.CERTIFICATE
Type: String representing file path
Description: Path to a file containing a PEM cerficate.
Related CURL Flags: CURLOPT_CERT
HTTP.SSL.KEY
Type: String representing file path
Description: Same as HTTP.SSL.CERTIFICATE, and should usually have the same value.
Related CURL Flags: CURLOPT_SSLKEY
HTTP.SSL.KEYPASSWORD
Type: String representing password
Description: Password for accessing the HTTP.SSL.KEY/HTTP.SSL.CERTIFICATE
Related CURL Flags: CURLOPT_KEYPASSWORD
HTTP.SSL.CAPATH
Type: String representing directory
Description: Path to a directory containing trusted certificates for validating server certificates.
Related CURL Flags: CURLOPT_CAPATH
HTTP.SSL.VALIDATE
Type: boolean ("1"/"0")
Description: Cause the client to verify the server's presented certificate.
Related CURL Flags: CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST
HTTP.TIMEOUT
Type: String ("dddddd")
Description: Specify the maximum time in seconds that you allow the http transfer operation to take.
Related CURL Flags: CURLOPT_TIMEOUT, CURLOPT_NOSIGNAL
HTTP.PROXY_SERVER
Type: String representing url to access the proxy: (e.g.http://[username:password@]host[:port])
Description: Specify the needed information for accessing a proxy.
Related CURL Flags: CURLOPT_PROXY, CURLOPT_PROXYHOST, CURLOPT_PROXYUSERPWD
HTTP.READ.BUFFERSIZE
Type: String ("dddddd")
Description: Specify the the internal buffer size for curl reads.
Related CURL Flags: CURLOPT_BUFFERSIZE, CURL_MAX_WRITE_SIZE (16kB),
CURL_MAX_READ_SIZE (512kB).
HTTP.KEEPALIVE
Type: String ("on|n/m")
Description: Specify that TCP KEEPALIVE should be enabled and that the associated idle wait time is n and that the associated repeat interval is m. If the value is of the form is the string "on", then turn on keepalive, but do not set idle or interval.
Related CURL Flags: CURLOPT_TCP_KEEPALIVE, CURLOPT_TCP_KEEPIDLE,
CURLOPT_TCP_KEEPINTVL.
</pre>
The related curl flags line indicates the curl flags modified by this
key. See the libcurl documentation of the curl_easy_setopt() function
for more detail (http://curl.haxx.se/libcurl/c/curl_easy_setopt.html).
For ESG client side key support, the following entries must be specified:
\code
HTTP.SSL.VALIDATE
HTTP.COOKIEJAR
HTTP.SSL.CERTIFICATE
HTTP.SSL.KEY
HTTP.SSL.CAPATH
\endcode
Additionally, for ESG, the HTTP.SSL.CERTIFICATE and HTTP.SSL.KEY
entries should have same value, which is the file path for the
certificate produced by MyProxyLogon. The HTTP.SSL.CAPATH entry should
be the path to the "certificates" directory produced by MyProxyLogon.
*/

353
NUG/bestpractices.md Normal file
View File

@ -0,0 +1,353 @@
Writing NetCDF Files: Best Practices {#BestPractices}
====================================
[TOC]
Best Practices {#bp_Best_Practices}
=====================================
## Conventions {#bp_Conventions}
While netCDF is intended for "self-documenting data", it is often
necessary for data writers and readers to agree upon attribute
conventions and representations for discipline-specific data structures.
These agreements are written up as human readable documents called
***netCDF conventions***.
Use an existing Convention if possible. See the list of [registered
conventions](/software/netcdf/conventions.html).
The CF Conventions are recommended where applicable, especially for
gridded (model) datasets.
Document the convention you are using by adding the global attribute
"Conventions" to each netCDF file, for example:
This document refers to conventions for the netCDF *classic* data model.
For recommendations about conventions for the netCDF-4 *enhanced* data
model, see [Developing Conventions for
NetCDF-4](/netcdf/papers/nc4_conventions.html).
## Coordinate Systems {#bp_Coordinate-Systems}
A ***coordinate variable*** is a one-dimensional variable with the same
name as a dimension, which names the coordinate values of the dimension.
It must not have any missing data (for example, no `_FillValue` or
`missing_value` attributes) and must be strictly monotonic (values
increasing or decreasing). A two-dimensional variable of type char is a
***string-valued coordinate variable*** if it has the same name as its
first dimension, e.g.: **char time( time, time\_len);** all of its
strings must be unique. A variable's ***coordinate system*** is the set
of coordinate variables used by the variable. Coordinates that refer to
physical space are called ***spatial coordinates***, ones that refer to
physical time are called ***time coordinates***, ones that refer to
either physical space or time are called ***spatio-temporal
coordinates.***
- Make coordinate variables for every dimension possible (except for
string length dimensions).
- Give each coordinate variable at least `unit` and `long_name`
attributes to document its meaning.
- Use an existing netCDF [Convention](#Conventions) for your
coordinate variables, especially to identify
spatio-temporal coordinates.
- Use shared dimensions to indicate that two variables use the same
coordinates along that dimension. If two variables' dimensions are
not related, create separate dimensions for them, even if they
happen to have the same length.
## Variable Grouping {#bp_Variable-Grouping}
You may structure the data in a netCDF file in different ways, for
example putting related parameters into a single variable by adding an
extra dimension. Standard visualization and analysis software may have
trouble breaking that data out, however. On the other extreme, it is
possible to create different variables e.g. for different vertical
levels of the same parameter. However, standard visualization and
analysis software may have trouble grouping that data back together.
Here are some guidelines for deciding how to group your data into
variables:
- All of the data in a variable must be of the same type and should
have the same units of measurement.
- A variable's attributes should be applicable to all its data.
- If possible, all of the coordinate variables should be
spatio-temporal, with no extra dimensions.
- Use 4D spatio-temporal coordinate systems in preference to 3D. Use
3D spatio-temporal coordinate systems in preference to 2D.
- Vector valued (e.g. wind) parameters are legitimate uses of extra
dimensions. There are trade-offs between putting vectors in the same
variables vs. putting each component of a vector in a
different variable. Check that any visualization software you plan
to use can deal with the structure you choose.
- Think in terms of complete coordinate systems (especially
spatio-temporal), and organize your data into variables accordingly.
Variables with the same coordinate system implicitly form a group.
## Variable Attributes {#bp_Variable-Attributes}
- For each variable where it makes sense, add a **units** attribute,
using the [udunits](/software/udunits/index.html) conventions,
if possible.
- For each variable where it makes sense, add a **long\_name ****
attribute, which is a human-readable descriptive name for
the variable. This could be used for labeling plots, for example.
## Strings and Variables of type char {#bp_Strings-and-Variables-of-type-char}
NetCDF-3 does not have a primitive **String** type, but does have arrays
of type **char**, which are 8 bits in size. The main difference is that
Strings are variable length arrays of chars, while char arrays are fixed
length. Software written in C usually depends on Strings being zero
terminated, while software in Fortran and Java do not. Both C
(*nc\_get\_vara\_text*) and Java (*ArrayChar.getString*) libraries have
convenience routines that read char arrays and convert to Strings.
- Do not use char type variables for numeric data, use byte type
variables instead.
- Consider using a global Attribute instead of a Variable to store a
String applicable to the whole dataset.
- When you want to store arrays of Strings, use a multidimensional
char array. All of the Strings will be the same length.
- There are 3 strategies for writing variable length Strings and
zero-byte termination:
1. *Fortran convention*: pad with blanks and never terminate with a
zero byte.
2. *C convention*: pad with zeros and always terminate with a
zero byte.
3. *Java convention*: You don't need to store a trailing zero byte,
but pad trailing unused characters with zero bytes.
- When reading, trim zeros and blanks from the end of the char array
and if in C, add a zero byte terminator.
## Calendar Date/Time {#bp_Calendar-Date-Time}
Time as a fundamental unit means a time interval, measured in seconds. A
Calendar date/time is a specific instance in real, physical time. Dates
are specified as an interval from some ***reference time*** e.g. "days
elapsed since Greenwich mean noon on 1 January 4713 BCE". The reference
time implies a system of counting time called a ***calendar*** (e.g.
Gregorian calendar) and a textual representation (e.g. [ISO
8601](http://www.cl.cam.ac.uk/%7Emgk25/iso-time.html)).
There are two strategies for storing a date/time into a netCDF variable.
One is to encode it as a numeric value and a unit that includes the
reference time, e.g. "seconds since 2001-1-1 0:0:0" or"days since
2001-1-1 0:0:0" . The other is to store it as a String using a standard
encoding and Calendar. The former is more compact if you have more than
one date, and makes it easier to compute intervals between two dates.
Unidata's [udunits](/software/udunits/) package provides a convenient
way to implement the first strategy. It uses the ISO 8601 encoding and a
hybrid Gregorian/Julian calendar, but udunits does not support use of
other Calendars or encodings for the reference time. However the ncdump
"-T" option can display numeric times that use udunits (and optionally
climate calendars) as ISO 8601 strings that are easy for humans to
interpret.
- If your data uses real, physical time that is well represented using
the Gregorian/Julian calendar, encode it as an interval from a
reference time, and add a units attribute which uses a
udunits-compatible time unit. If the data assumes one of the
non-standard calendars mentioned in the CF Conventions, specify that
with a Calendar attribute. Readers can then use the udunits package
to manipulate or format the date values, and the ncdump utility can
display them with either numeric or string representation.
- If your data uses a calendar not supported by the CF Conventions,
make it compatible with existing date manipulation packages if
possible (for example, java.text.SimpleDateFormat).
- Add multiple sets of time encodings if necessary to allow different
readers to work as well as possible.\
## Unsigned Data {#bp_Unsigned-Data}
NetCDF-3 does not have unsigned integer primitive types.
- To be completely safe with unknown readers, widen the data type, or
use floating point.
- You can use the corresponding signed types to store unsigned data
only if all client programs know how to interpret this correctly.
- A new proposed convention is to create a variable attribute
`_Unsigned = "true"` to indicate that integer data should be treated
as unsigned.
## Packed Data Values {#bp_Packed-Data-Values}
Packed data is stored in a netCDF file by limiting precision and using a
smaller data type than the original data, for example, packing
double-precision (64-bit) values into short (16-bit) integers. The
C-based netCDF libraries do not do the packing and unpacking. (The
[netCDF Java library](/software/netcdf-java/) will do automatic
unpacking when the
[VariableEnhanced](/software/netcdf-java/v4.1/javadocAll/ucar/nc2/dataset/VariableEnhanced.html)
Interface is used. For details see
[EnhancedScaleMissing](/software/netcdf-java/v4.1/javadocAll/ucar/nc2/dataset/EnhanceScaleMissing.html)).
- Each variable with packed data has two attributes called
**scale\_factor** and **add\_offset**, so that the packed data may
be read and unpacked using the formula:
> ***unpacked\_data\_value = packed\_data\_value \* scale\_factor +
> add\_offset***
- The type of the stored variable is the packed data type, typically
byte, short or int.
- The type of the scale\_factor and add\_offset attributes should be
the type that you want the unpacked data to be, typically float
or double.
- To avoid introducing a bias into the unpacked values due to
truncation when packing, the data provider should round to the
nearest integer rather than just truncating towards zero before
writing the data:
> ***packed\_data\_value = nint((unpacked\_data\_value -
> add\_offset) / scale\_factor)***
Depending on whether the packed data values are intended to be
interpreted by the reader as signed or unsigned integers, there are
alternative ways for the data provider to compute the *scale\_factor*
and *add\_offset* attributes. In either case, the formulas above apply
for unpacking and packing the data.
A conventional way to indicate whether a byte, short, or int variable is
meant to be interpreted as unsigned, even for the netCDF-3 classic model
that has no external unsigned integer type, is by providing the special
variable attribute `_Unsigned` with value `"true"`. However, most
existing data for which packed values are intended to be interpreted as
unsigned are stored without this attribute, so readers must be aware of
packing assumptions in this case. In the enhanced netCDF-4 data model,
packed integers may be declared to be of the appropriate unsigned type.
Let *n* be the number of bits in the packed type, and assume *dataMin*
and *dataMax* are the minimum and maximum values that will be used for a
variable to be packed.
- If the packed values are intended to be interpreted as signed
integers (the default assumption for classic model data), you may
use:
> *scale\_factor =(dataMax - dataMin) / (2^n^ - 1)*
> *add\_offset = dataMin + 2^n\\ -\\ 1^ \* scale\_factor*
- If the packed values are intended to be interpreted as unsigned (for
example, when read in the C interface using the `nc_get_var_uchar()`
function), use:
> *scale\_factor =(dataMax - dataMin) / (2^n^ - 1)*
> *add\_offset = dataMin*
- In either the signed or unsigned case, an alternate formula may be
used for the add\_offset and scale\_factor packing parameters that
reserves a packed value for a special value, such as an indicator of
missing data. For example, to reserve the minimum packed value
(-2^n\\ -\\ 1^) for use as a special value in the case of signed
packed values:
> *scale\_factor =(dataMax - dataMin) / (2^n^ - 2)*
> *add\_offset = (dataMax + dataMin) / 2*
- If the packed values are unsigned, then the analogous formula that
reserves 0 as the packed form of a special value would be:
> *scale\_factor =(dataMax - dataMin) / (2^n^ - 2)*
> *add\_offset = dataMin - scale\_factor*
- Example, packing 32-bit floats into 16-bit shorts:
variables:
short data( z, y, x);
data:scale_offset = 34.02f;
data:add_offset = 1.54f;
- The `units` attribute applies to unpacked values.
## Missing Data Values {#bp_Missing-Data-Values}
***Missing data*** is a general name for data values that are invalid,
never written, or missing. The netCDF library itself does not handle
these values in any special way, except that the value of a `_FillValue`
attribute, if any, is used in pre-filling unwritten data. (The
Java-netCDF library will assist in recognizing these values when
reading, see class **VariableStandardized**).
- Default fill values for each type are available in the C-based
interfaces, and are defined in the appropriate header files. For
example, in the C interface, NC\_FILL\_FLOAT and NC\_FILL\_DOUBLE
are numbers near 9.9692e+36 that are returned when you try to read
values that were never written. Writing, reading, and testing for
equality with these default fill values works portably on the
platforms on which netCDF has been tested.
- The `_FillValue` attribute should have the same data type as the
variable it describes. If the variable is packed using
`scale_factor` and `add_offset` attributes, the `_FillValue`
attribute should have the data type of the packed data.
- Another way of indicating missing values for real type data is to
store an IEEE **NaN** floating point value. The advantage of this is
that any computation using a NaN results in a NaN. Client software
must know to look for NaNs, however, and detection of NaNs is
tricky, since any comparison with a NaN is required to return
*false*.
- In Java, you can use **Double.NaN** and **Float.NaN** constants.
- In many C compilers, you can generate a NaN value using **double
nan = 0.0 / 0.0;**
- Alternatively or in addition, set the **valid\_range** attribute for
each variable that uses missing values, and make sure all valid data
is within that range, and all missing or invalid data is outside of
that range. Again, the client software must recognize and make use
of this information. Example:
variables:
float data( z, y, x);
data:valid_range = -999.0f, 999.0f;
If the variable is packed using `scale_factor` and `add_offset`
attributes, the `valid_range` attribute should have the data type of
the packed data.
If the variable is unsigned the `valid_range` values should be
widened if needed and stored as unsigned integers.
## Miscellaneous tips {#bp_Miscellaneous-tips}
- To define a file whose structure is known in advance, write a CDL
file and create the netCDF file using
[ncgen](/cgi-bin/man-cgi?ncgen). Then write the data into the netCDF
file using your program. This is typically much easier than
programming all of the create calls yourself.
- For the netCDF classic or 64-bit-offset formats, it's possible to
reserve extra space in the file when it is created so that you can
later add additional attributes or non-record variables without
copying all the data. (This is not necessary for netCDF-4 files,
because metadata can be added efficiently to such files.) See the [C
man-page reference documentation](/cgi-bin/man-cgi?netcdf+-s3) (or
the [Fortran reference documentation](/cgi-bin/man-cgi?netcdf+-s3f))
for `nc__create` and `nc__enddef` (`nf__create` and `nf__enddef`
for Fortran) for more details on reserving extra space in
the header.
## Spelling netCDF: Best Practices {#bp_Spelling-netCDF-Best-Practices}
There are only 3 correct spellings of "netCDF":
1. **netCDF:** The original spelling of the name of the data model,
API, and format. The acronym stands for network Common Data Form
(not Format), and the "CDF" part was capitalized in part to pay
homage to the NASA "CDF" data model which the netCDF data
model extended.
2. **netcdf:** Used in certain file names, such as:
#include <netcdf.h>
3. **NetCDF**: Used in titles and at the beginning of sentences, where
"netCDF" is awkward or violates style guidelines.
All other forms, and most especially "Netcdf", are considered vulgar and
a sign of ill-breeding or misspent youth, analogous to the egregious but
common misspelling "JAVA" used by those who are new to the language or
who mistakenly think it is an acronym.\

6
NUG/cleanup.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
rm -rf html
rm -rf latex
rm -rf *~

605
NUG/filters.md Normal file
View File

@ -0,0 +1,605 @@
NetCDF-4 Filter Support
============================
<!-- double header is needed to workaround doxygen bug -->
NetCDF-4 Filter Support {#filters}
============================
[TOC]
# Introduction {#filters_intro}
The HDF5 library (1.8.11 and later)
supports a general filter mechanism to apply various
kinds of filters to datasets before reading or writing.
The netCDF enhanced (aka netCDF-4) library inherits this
capability since it depends on the HDF5 library.
Filters assume that a variable has chunking
defined and each chunk is filtered before
writing and "unfiltered" after reading and
before passing the data to the user.
The most common kind of filter is a compression-decompression
filter, and that is the focus of this document.
HDF5 supports dynamic loading of compression filters using the following
process for reading of compressed data.
1. Assume that we have a dataset with one or more variables that
were compressed using some algorithm. How the dataset was compressed
will be discussed subsequently.
2. Shared libraries or DLLs exist that implement the compress/decompress
algorithm. These libraries have a specific API so that the HDF5 library
can locate, load, and utilize the compressor.
These libraries are expected to installed in a specific
directory.
# Enabling A Compression Filter {#filters_enable}
In order to compress a variable, the netcdf-c library
must be given three pieces of information:
(1) some unique identifier for the filter to be used,
(2) a vector of parameters for
controlling the action of the compression filter, and
(3) a shared library implementation of the filter.
The meaning of the parameters is, of course,
completely filter dependent and the filter
description [3] needs to be consulted. For
bzip2, for example, a single parameter is provided
representing the compression level.
It is legal to provide a zero-length set of parameters.
Defaults are not provided, so this assumes that
the filter can operate with zero parameters.
Filter ids are assigned by the HDF group. See [4]
for a current list of assigned filter ids.
Note that ids above 32767 can be used for testing without
registration.
The first two pieces of information can be provided in one of three ways:
using __ncgen__, via an API call, or via command line parameters to __nccopy__.
In any case, remember that filtering also requires setting chunking, so the
variable must also be marked with chunking information.
## Using The API {#filters_API}
The necessary API methods are included in __netcdf.h__ by default.
One API method is for setting the filter to be used
when writing a variable. The relevant signature is
as follows.
````
int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
````
This must be invoked after the variable has been created and before
__nc_enddef__ is invoked.
A second API methods makes it possible to query a variable to
obtain information about any associated filter using this signature.
````
int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
````
The filter id will be returned in the __idp__ argument (if non-NULL),
the number of parameters in __nparamsp__ and the actual parameters in
__params__. As is usual with the netcdf API, one is expected to call
this function twice. The first time to get __nparams__ and the
second to get the parameters in client-allocated memory.
## Using ncgen {#filters_NCGEN}
In a CDL file, compression of a variable can be specified
by annotating it with the following attribute:
* ''_Filter'' -- a string containing a comma separated list of
constants specifying (1) the filter id to apply, and (2)
a vector of constants representing the
parameters for controlling the operation of the specified filter.
See the section on the <a href="#Syntax">parameter encoding syntax</a>
for the details on the allowable kinds of constants.
This is a "special" attribute, which means that
it will normally be invisible when using
__ncdump__ unless the -s flag is specified.
### Example CDL File (Data elided)
````
netcdf bzip2 {
dimensions:
dim0 = 4 ; dim1 = 4 ; dim2 = 4 ; dim3 = 4 ;
variables:
float var(dim0, dim1, dim2, dim3) ;
var:_Filter = "307,9" ;
var:_Storage = "chunked" ;
var:_ChunkSizes = 4, 4, 4, 4 ;
data:
...
}
````
## Using nccopy {#filters_NCCOPY}
When copying a netcdf file using __nccopy__ it is possible
to specify filter information for any output variable by
using the "-F" option on the command line; for example:
````
nccopy -F "var,307,9" unfiltered.nc filtered.nc
````
Assume that __unfiltered.nc__ has a chunked but not bzip2 compressed
variable named "var". This command will create that variable in
the __filtered.nc__ output file but using filter with id 307
(i.e. bzip2) and with parameter(s) 9 indicating the compression level.
See the section on the <a href="#Syntax">parameter encoding syntax</a>
for the details on the allowable kinds of constants.
The "-F" option can be used repeatedly as long as the variable name
part is different. A different filter id and parameters can be
specified for each occurrence.
It can be convenient to specify that the same compression is to be
applied to more than one variable. To support this, two additional
*-F* cases are defined.
1. ````-F *,...``` means apply the filter to all variables in the dataset.
2. ````-F v1|v2|..,...``` means apply the filter to a multiple variables.
Note that the characters '*' and '|' are bash reserved characters,
so you will probably need to escape or quote the filter spec in
that environment.
As a rule, any input filter on an input variable will be applied
to the equivalent output variable -- assuming the output file type
is netcdf-4. It is, however, sometimes convenient to suppress
output compression either totally or on a per-variable basis.
Total suppression of output filters can be accomplished by specifying
a special case of "-F", namely this.
````
nccopy -F none input.nc output.nc
````
The expression ````-F *,none```` is equivalent to ````-F none````.
Suppression of output filtering for a specific set of variables
can be accomplished using these formats.
````
nccopy -F "var,none" input.nc output.nc
nccopy -F "v1|v2|...,none" input.nc output.nc
````
where "var" and the "vi" are the fully qualified name of a variable.
The rules for all possible cases of the "-F none" flag are defined
by this table.
<table>
<tr><th>-F none<th>-Fvar,...<th>Input Filter<th>Applied Output Filter
<tr><td>true<td>unspecified<td>NA<td>unfiltered
<tr><td>true<td>-Fvar,none<td>NA<td>unfiltered
<tr><td>true<td>-Fvar,...<td>NA<td>use output filter
<tr><td>false<td>unspecified<td>defined<td>use input filter
<tr><td>false<td>-Fvar,none<td>NA<td>unfiltered
<tr><td>false<td>-Fvar,...<td>NA<td>use output filter
<tr><td>false<td>unspecified<td>none<td>unfiltered
</table>
# Parameter Encode/Decode {#filters_paramcoding}
The parameters passed to a filter are encoded internally as a vector
of 32-bit unsigned integers. It may be that the parameters
required by a filter can naturally be encoded as unsigned integers.
The bzip2 compression filter, for example, expects a single
integer value from zero thru nine. This encodes naturally as a
single unsigned integer.
Note that signed integers and single-precision (32-bit) float values
also can easily be represented as 32 bit unsigned integers by
proper casting to an unsigned integer so that the bit pattern
is preserved. Simple integer values of type short or char
(or the unsigned versions) can also be mapped to an unsigned
integer by truncating to 16 or 8 bits respectively and then
zero extending.
Machine byte order (aka endian-ness) is an issue for passing
some kinds of parameters. You might define the parameters when
compressing on a little endian machine, but later do the
decompression on a big endian machine. Byte order is not an
issue for 32-bit values because HDF5 takes care of converting
them between the local machine byte order and network byte
order.
Parameters whose size is larger than 32-bits present a byte order problem.
This specifically includes double precision floats and (signed or unsigned)
64-bit integers. For these cases, the machine byte order issue must be
handled, in part, by the compression code. This is because HDF5 will treat,
for example, an unsigned long long as two 32-bit unsigned integers
and will convert each to network order separately. This means that
on a machine whose byte order is different than the machine in which
the parameters were initially created, the two integers will be separately
endian converted. But this will be incorrect for 64-bit values.
So, we have this situation:
1. the 8 bytes come in as native machine order for the machine
doing the call to *nc_def_var_filter*.
2. HDF5 divides the 8 bytes into 2 four byte pieces and ensures that each piece
is in network (big) endian order.
3. When the filter is called, the two pieces are returned in the same order
but with the bytes in each piece consistent with the native machine order
for the machine executing the filter.
## Encoding Algorithms
In order to properly extract the correct 8-byte value, we need to ensure
that the values stored in the HDF5 file have a known format independent of
the native format of the creating machine.
The idea is to do sufficient manipulation so that HDF5
will store the 8-byte value as a little endian value
divided into two 4-byte integers.
Note that little-endian is used as the standard
because it is the most common machine format.
When read, the filter code needs to be aware of this convention
and do the appropriate conversions.
This leads to the following set of rules.
### Encoding
1. Encode on little endian (LE) machine: no special action is required.
The 8-byte value is passed to HDF5 as two 4-byte integers. HDF5 byte
swaps each integer and stores it in the file.
2. Encode on a big endian (BE) machine: several steps are required:
1. Do an 8-byte byte swap to convert the original value to little-endian
format.
2. Since the encoding machine is BE, HDF5 will just store the value.
So it is necessary to simulate little endian encoding by byte-swapping
each 4-byte integer separately.
3. This doubly swapped pair of integers is then passed to HDF5 and is stored
unchanged.
### Decoding
1. Decode on LE machine: no special action is required.
HDF5 will get the two 4-bytes values from the file and byte-swap each
separately. The concatenation of those two integers will be the expected
LE value.
2. Decode on a big endian (BE) machine: the inverse of the encode case must
be implemented.
1. HDF5 sends the two 4-byte values to the filter.
2. The filter must then byte-swap each 4-byte value independently.
3. The filter then must concatenate the two 4-byte values into a single
8-byte value. Because of the encoding rules, this 8-byte value will
be in LE format.
4. The filter must finally do an 8-byte byte-swap on that 8-byte value
to convert it to desired BE format.
To support these rules, some utility programs exist and are discussed in
<a href="#AppendixA">Appendix A</a>.
# Filter Specification Syntax {#filters_syntax}
Both of the utilities
<a href="#NCGEN">__ncgen__</a>
and
<a href="#NCCOPY">__nccopy__</a>
allow the specification of filter parameters in text format.
These specifications consist of a sequence of comma
separated constants. The constants are converted
within the utility to a proper set of unsigned int
constants (see the <a href="#ParamEncode">parameter encoding section</a>).
To simplify things, various kinds of constants can be specified
rather than just simple unsigned integers. The utilities will encode
them properly using the rules specified in
the section on <a href="#filters_paramcoding">parameter encode/decode</a>.
The currently supported constants are as follows.
<table>
<tr halign="center"><th>Example<th>Type<th>Format Tag<th>Notes
<tr><td>-17b<td>signed 8-bit byte<td>b|B<td>Truncated to 8 bits and zero extended to 32 bits
<tr><td>23ub<td>unsigned 8-bit byte<td>u|U b|B<td>Truncated to 8 bits and zero extended to 32 bits
<tr><td>-25S<td>signed 16-bit short<td>s|S<td>Truncated to 16 bits and zero extended to 32 bits
<tr><td>27US<td>unsigned 16-bit short<td>u|U s|S<td>Truncated to 16 bits and zero extended to 32 bits
<tr><td>-77<td>implicit signed 32-bit integer<td>Leading minus sign and no tag<td>
<tr><td>77<td>implicit unsigned 32-bit integer<td>No tag<td>
<tr><td>93U<td>explicit unsigned 32-bit integer<td>u|U<td>
<tr><td>789f<td>32-bit float<td>f|F<td>
<tr><td>12345678.12345678d<td>64-bit double<td>d|D<td>LE encoding
<tr><td>-9223372036854775807L<td>64-bit signed long long<td>l|L<td>LE encoding
<tr><td>18446744073709551615UL<td>64-bit unsigned long long<td>u|U l|L<td>LE encoding
</table>
Some things to note.
1. In all cases, except for an untagged positive integer,
the format tag is required and determines how the constant
is converted to one or two unsigned int values.
The positive integer case is for backward compatibility.
2. For signed byte and short, the value is sign extended to 32 bits
and then treated as an unsigned int value.
3. For double, and signed|unsigned long long, they are converted
as specified in the section on
<a href="#filters_paramcoding">parameter encode/decode</a>.
Dynamic Loading Process {#filters_Process}
==========
The documentation[1,2] for the HDF5 dynamic loading was (at the time
this was written) out-of-date with respect to the actual HDF5 code
(see HDF5PL.c). So, the following discussion is largely derived
from looking at the actual code. This means that it is subject to change.
Plugin directory {#filters_Plugindir}
----------------
The HDF5 loader expects plugins to be in a specified plugin directory.
The default directory is:
* "/usr/local/hdf5/lib/plugin” for linux/unix operating systems (including Cygwin)
* “%ALLUSERSPROFILE%\\hdf5\\lib\\plugin” for Windows systems, although the code
does not appear to explicitly use this path.
The default may be overridden using the environment variable
__HDF5_PLUGIN_PATH__.
Plugin Library Naming {#filters_Pluginlib}
---------------------
Given a plugin directory, HDF5 examines every file in that
directory that conforms to a specified name pattern
as determined by the platform on which the library is being executed.
<table>
<tr halign="center"><th>Platform<th>Basename<th>Extension
<tr halign="left"><td>Linux<td>lib*<td>.so*
<tr halign="left"><td>OSX<td>lib*<td>.so*
<tr halign="left"><td>Cygwin<td>cyg*<td>.dll*
<tr halign="left"><td>Windows<td>*<td>.dll
</table>
Plugin Verification {#filters_Pluginverify}
-------------------
For each dynamic library located using the previous patterns,
HDF5 attempts to load the library and attempts to obtain information
from it. Specifically, It looks for two functions with the following
signatures.
1. __H5PL_type_t H5PLget_plugin_type(void)__ --
This function is expected to return the constant value
__H5PL_TYPE_FILTER__ to indicate that this is a filter library.
2. __const void* H5PLget_plugin_info(void)__ --
This function returns a pointer to a table of type __H5Z_class2_t__.
This table contains the necessary information needed to utilize the
filter both for reading and for writing. In particular, it specifies
the filter id implemented by the library and if must match that id
specified for the variable in __nc_def_var_filter__ in order to be used.
If plugin verification fails, then that plugin is ignored and
the search continues for another, matching plugin.
Debugging {#filters_Debug}
-------
Debugging plugins can be very difficult. You will probably
need to use the old printf approach for debugging the filter itself.
One case worth mentioning is when you have a dataset that is
using an unknown filter. For this situation, you need to
identify what filter(s) are used in the dataset. This can
be accomplished using this command.
````
ncdump -s -h <dataset filename>
````
Since ncdump is not being asked to access the data (the -h flag), it
can obtain the filter information without failures. Then it can print
out the filter id and the parameters (the -s flag).
Test Case {#filters_TestCase}
-------
Within the netcdf-c source tree, the directory
__netcdf-c/nc_test4__ contains a test case (__test_filter.c__) for
testing dynamic filter writing and reading using
bzip2. Another test (__test_filter_misc.c__) validates
parameter passing. These tests are disabled if __--enable-shared__
is not set or if __--enable-netcdf-4__ is not set.
Example {#filters_Example}
-------
A slightly simplified version of the filter test case is also
available as an example within the netcdf-c source tree
directory __netcdf-c/examples/C. The test is called __filter_example.c__
and it is executed as part of the __run_examples4.sh__ shell script.
The test case demonstrates dynamic filter writing and reading.
The files __example/C/hdf5plugins/Makefile.am__
and __example/C/hdf5plugins/CMakeLists.txt__
demonstrate how to build the hdf5 plugin for bzip2.
Notes
==========
Memory Allocation Issues
-----------
Starting with HDF5 version 1.10.x, the plugin code MUST be
careful when using the standard *malloc()*, *realloc()*, and
*free()* function.
In the event that the code is allocating, reallocating, for
free'ing memory that either came from or will be exported to the
calling HDF5 library, then one MUST use the corresponding HDF5
functions *H5allocate_memory()*, *H5resize_memory()*,
*H5free_memory()* [5] to avoid memory failures.
Additionally, if your filter code leaks memory, then the HDF5 library
generates a failure something like this.
````
H5MM.c:232: H5MM_final_sanity_check: Assertion `0 == H5MM_curr_alloc_bytes_s' failed.
````
One can look at the the code in plugins/H5Zbzip2.c and H5Zmisc.c to see this.
SZIP Issues
-----------
The current szip plugin code in the HDF5 library
has some behaviors that can catch the unwary.
Specifically, this filter may do two things.
1. Add extra parameters to the filter parameters: going from
the two parameters provided by the user to four parameters
for internal use. It turns out that the two parameters provided
when calling nc_def_var_filter correspond to the first two
parameters of the four parameters returned by nc_inq_var_filter.
2. Change the values of some parameters: the value of the
__options_mask__ argument is known to add additional flag bits,
and the __pixels_per_block__ parameter may be modified.
The reason for these changes is has to do with the fact that
the szip API provided by the underlying H5Pset_szip function
is actually a subset of the capabilities of the real szip implementation.
Presumably this is for historical reasons.
In any case, if the caller uses the __nc_inq_var_szip__, then
the values returned may differ from those originally specified.
If one used the __nc_inq_var_filter__ API calls, it may be the case that
both the number of parameters and the values will differ from the original
call to __nc_def_var_filter__.
Supported Systems
-----------------
The current matrix of OS X build systems known to work is as follows.
<table>
<tr><th>Build System<th>Supported OS
<tr><td>Automake<td>Linux, Cygwin
<tr><td>Cmake<td>Linux, Cygwin, Visual Studio
</table>
Generic Plugin Build
--------------------
If you do not want to use Automake or Cmake, the following
has been known to work.
````
gcc -g -O0 -shared -o libbzip2.so <plugin source files> -L${HDF5LIBDIR} -lhdf5_hl -lhdf5 -L${ZLIBDIR} -lz
````
Appendix A. Support Utilities {#filters_AppendixA}
==========
Two functions are exported from the netcdf-c library
for use by client programs and by filter implementations.
1. ````int NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);````
* idp will contain the filter id value from the spec.
* nparamsp will contain the number of 4-byte parameters
* paramsp will contain a pointer to the parsed parameters -- the caller
must free.
This function can parse filter spec strings as defined in
the section on <a href="#filters_syntax">Filter Specification Syntax</a>.
This function parses the first argument and returns several values.
2. ````int NC_filterfix8(unsigned char* mem8, int decode);````
* mem8 is a pointer to the 8-byte value either to fix.
* decode is 1 if the function should apply the 8-byte decoding algorithm
else apply the encoding algorithm.
This function implements the 8-byte conversion algorithms.
Before calling *nc_def_var_filter* (unless *NC_parsefilterspec* was used),
the client must call this function with the decode argument set to 0.
Inside the filter code, this function should be called with the decode
argument set to 1.
Examples of the use of these functions can be seen in the test program
*nc_test4/tst_filterparser.c*.
Appendix B. Programmatic Filter Definition {#filters_programmatic}
==========
HDF5 provides an API [6] to allow for the programmatic definition
of filters -- as opposed to using the HDF5_PLUGIN_PATH environment variable.
The idea is that instead of using dynamic shared libraries, the filter code
is compiled into the application and the relevant information
(namely an instance of *H5Z_class2_t*) is passed to the HDF5 library API.
Because it is anticipated that in the future, other plugin formats
will be used, this netcdf-c API is deliberately more general than
strictly required by HDF5.
## API Concepts
Three concepts are used in this API.
1. Format - this is an integer defining the format of the plugin.
Currently, only *NC_FILTER_FORMAT_HDF5* is defined and corresponds
to the existing HDF5 plugin format.
2. ID - this is an integer that is a unique identifier for the filter.
This value is interpreted in the context of the format, so the same
id might be assigned to different filters if the format is different.
3. The structure *NC_FILTER_INFO* that provides generic information
to the API and has a placeholder for format-specific information.
typedef struct NC_FILTER_INFO {
int version; /* Of this structure */
int format; /* Controls actual type of this structure */
int id; /* Must be unique WRT format */
void* info; /* The filter info as defined by the format. */
} NC_FILTER_INFO;
When the format is the value NC_FILTER_FORMAT_HDF5,
then the info field is a pointer to an instance of
H5Z_class2_t as define in H5Zpublic.h.
The use of void* is, of course, to allow for passing arbitrary objects.
### NetCDF API
The following function signatures are provided (see *netcdf_filter.h*).
1. Register a filter
int nc_filter_register(NC_FILTER_INFO* filter_info);
Register a filter whose format and ID are specified in the 'filter_info'
argument.
2. Unregister a filter
int nc_filter_unregister(int format, int id);
Unregister the filter specified by the id. Note that only
filters registered using 'nc_filter_register' can be unregistered.
3. Inquire about a filter
int nc_filter_inq(int format, int id, NC_FILTER_INFO* filter_info);
Unregister the filter specified by the id. Note that only
filters registered using 'nc_filter_register' can be inquired.
The 'filter_info' is filled with a copy of the original argument to
'nc_filter_register'.
### Example
static const H5Z_class2_t H5Z_REG[1] = {
...
};
...
NC_FILTER_INFO info;
...
info.version = NC_FILTER_INFO_VERSION;
info.format = NC_FILTER_FORMAT_HDF5;
info.id = FILTER_ID;
info.info = (void*)&H5Z_REG[0];
stat = nc_filter_register(&info);
...
memset(&info,0,sizeof(NC_FILTER_INFO));
stat = nc_filter_inq(NC_FILTER_FORMAT_HDF5, FILTER_ID, &info);
...
stat = nc_filter_unregister(NC_FILTER_FORMAT_HDF5, FILTER_ID);
# References {#filters_References}
1. https://support.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters/HDF5DynamicallyLoadedFilters.pdf
2. https://support.hdfgroup.org/HDF5/doc/TechNotes/TechNote-HDF5-CompressionTroubleshooting.pdf
3. https://portal.hdfgroup.org/display/support/Contributions#Contributions-filters
4. https://support.hdfgroup.org/services/contributions.html#filters
5. https://support.hdfgroup.org/HDF5/doc/RM/RM_H5.html
6. https://confluence.hdfgroup.org/display/HDF5/Filters
# Point of Contact
__Author__: Dennis Heimbigner<br>
__Email__: dmh at ucar dot edu
__Initial Version__: 1/10/2018<br>
__Last Revised__: 2/5/2018

2932
NUG/guide.dox Normal file

File diff suppressed because it is too large Load Diff

2923
NUG/guide.md Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

4
NUG/images/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
EXTRA_DIST = aqua.jpg chunking2.png compatibility3.png compression.png \
groups.png nc4-model.png ncatts.png nc-classic-uml.png nccoords.png \
ncfile.png pnetcdf.png terra.jpg netcdf_architecture.png \
deptree.jpg InstallTreeWindows.png

BIN
NUG/images/aqua.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
NUG/images/chunking2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

BIN
NUG/images/compression.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
NUG/images/deptree.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
NUG/images/groups.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
NUG/images/nc4-model.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
NUG/images/ncatts.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
NUG/images/nccoords.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
NUG/images/ncfile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
NUG/images/pnetcdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
NUG/images/terra.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

500
NUG/install.md Normal file
View File

@ -0,0 +1,500 @@
Getting and Building netCDF {#getting_and_building_netcdf}
=============================
[TOC]
This document is for getting and building the netCDF C library and utilities for the most recent released version. Other libraries that depend on the netCDF C library, such as the Fortran, Python, Java, and C++ libraries, are available as separate distributions that can be optionally built and installed after the C library is successfully installed. The netCDF-Java library is independent of the netCDF C library unless writing netCDF-4 files from Java is required.
Getting netCDF-C {#getting}
=========================
* For information regarding the netCDF-Fortran libraries, see \subpage building_netcdf_fortran.
* Functionality to make it easier to build netcdf-fortran as part of the netcdf-c build for *non-MSVC* builds may be enabled at configure time by using the following **Highly Experimental** options:
* Autotools: `--enable-remote-fortran-bootstrap`
* CMake: `-DENABLE_REMOTE_FORTRAN_BOOTSTRAP=ON`
For more details, see the <a href="https://github.com/Unidata/netcdf-c/blob/master/RELEASE_NOTES.md">draft instructions</a> in the Release Notes under the `4.3.3-rc3` section.
Getting pre-built netCDF-C libraries. {#sec_get_pre_built}
-------------------------------------
The easiest way to get netCDF is through a package management program,
such as rpm, yum, homebrew, macports, adept, and others. NetCDF is
available from many different repositories, including the default Red
Hat and Ubuntu repositories.
When getting netCDF from a software repository, you should get a
development version that includes the netcdf.h header file. A
development version will typically have a name such as "netcdf-devel"
or "libnetcdf-dev".
Instructions for installing and using pre-built libraries for Windows may be found here: \ref winbin.
Getting the latest netCDF-C Source Code {#sec_get_source}
----------------------------------------
The netCDF-C source code is hosted from the <a href="http://github.com/Unidata/netcdf-c" >Unidata GitHub repository</a>.
Two options are available for building from source:
* The latest release.
* The developer snapshot.
### The latest release {#sec_latest_release}
The latest full release may be <a href="http://github.com/Unidata/netcdf-c/releases" >downloaded from GitHub</a>.
Source files are available in `.tar.gz` and `.zip` formats.
### The developer snapshot {#sec_dev_snapshot}
The developer snapshot may be cloned from GitHub directly by using the `git` command.
> $ git clone http://github.com/Unidata/netcdf-c netcdf-c
**Note:**
*The developer snapshot release contains bug-fixes and new features added since the last full release, but may also contain new bugs, as it is not tested as extensively as the full release.*
Building netCDF-C {#building}
===========================
The netCDF-C library and utilities require third-party libraries for
full functionality. (See \ref architecture).
* \ref build_default
* \ref build_classic
* \ref build_hdf4
* \ref build_parallel
* \ref building_netcdf_fortran
* \ref configure_options
Requirements {#netcdf_requirements}
----------------------------------
* For netCDF-4 support
* HDF5 1.8.9 or later.
* HDF5 1.10.1 or later.
* zlib 1.2.5 or later (for netCDF-4 compression)
* curl 7.18.0 or later (for DAP remote access client support)
* For parallel I/O support on classic netCDF files
* PnetCDF 1.6.0 or later
> **Important Note**: When building netCDF-C library versions older than 4.4.1, use only HDF5 1.8.x versions. Combining older netCDF-C versions with newer HDF5 1.10 versions will create superblock 3 files that are not readable by lots of older software. See <a href="http://www.unidata.ucar.edu/blogs/news/entry/netcdf-4-4-1">this announcement</a> for more details.
CMake and Windows support {#sub}
--------------------------------
* \ref netCDF-CMake
* \subpage winbin
Building with netCDF-4 and the Remote Data Client {#build_default}
--------------------------------
The usual way of building netCDF requires the HDF5, zlib, and curl libraries. Versions required are at least HDF5 1.8.9, zlib 1.2.5, and curl 7.18.0 or later.
HDF5 and zlib packages are available from the <a href="http://www.hdfgroup.org/downloads/">HDF5 downloads site</a> and the <a href="http://www.zlib.net/">zlib home site</a>. If you wish to use the remote data client code, then you will also need libcurl, which can be obtained from the <a href="http://curl.haxx.se/download.html">curl website</a>.
> Note that for building netCDF, it is not necessary to build the HDF5 Fortran, C++, or Java API's. Only the HDF5 C library is used, even for netCDF Fortran or C++ libraries.
### Optional: szip support {#op_szip_support}
*Optionally*, you can also build netCDF-4 with the szip library (a.k.a. szlib). If building with szlib, get szip 2.0 or later. Technically, we mean that
the HDF5 library is built with szip support. The netcdf build will then
inherit szip support from the HDF5 library.
If you intend to write files with szip compression, then we suggest that you
use [libaec](https://gitlab.dkrz.de/k202009/libaec.git)
to avoid patent problems. That library can be used as a
drop-in replacement for the standard szip library.
If you plan to use the standard szip library,
then determine whether license restrictions on the use of szip apply to your situation. See the <a href="http://www.hdfgroup.org/doc_resource/SZIP/">web page on szip compression in HDF products</a>.
If `make check` fails for either `zlib` or `HDF5`, the problem must be resolved before the netCDF-4 installation can continue. For HDF5 problems, see the <a href="http://www.hdfgroup.org/services/support.html">HDF5 help services</a>.
### Building zlib from source {#build_zlib_from_source}
To build zlib from source, specify where you want to install zlib in a shell variable you will also use later (ZDIR, for example), and build it like this from the top-level zlib source directory
~~~~{.py}
$ # Build and install zlib
$ ZDIR=/usr/local
$ ./configure --prefix=${ZDIR}
$ make check
$ make install # or sudo make install, if root permissions required
~~~~
### Building hdf5 from source {#build_hdf5_from_source}
Next, specify where you want to install HDF5 in another shell variable, for example H5DIR, and build it from the HDF5 top-level source directory:
~~~~{.py}
$ # Build and install HDF5
$ H5DIR=/usr/local
$ ./configure --with-zlib=${ZDIR} --prefix=${H5DIR} --enable-hl
$ make check
$ make install # or sudo make install, if root permissions required
~~~~
If you are building HDF5 with the optional szip library, include the `--with-szlib=` option to specify where it was installed.
In all cases, the installation location specified with the `--prefix` option *must be different* from the source directory where the software is being built.
### Building netCDF-4 and the Remote Data Client from source {#build_nc4_dap_from_source}
Before building netCDF, you may need to add `${H5DIR}/lib` to the LD_LIBRARY_PATH environment variable if that lib directory is not searched by default. See the <a href="http://www.unidata.ucar.edu/netcdf/docs/faq.html#Shared%20Libraries">netCDF FAQ</a> for more details on using shared libraries.
Indicate where you want to install netCDF in another shell variable, for example NCDIR. Then run the netCDF configure script, specifying where HDF5 was installed using the CPPFLAGS and LDFLAGS environment variables. For example, from the top-level netCDF source directory:
~~~~{.py}
$ # Build and install netCDF-4
$ NCDIR=/usr/local
$ CPPFLAGS='-I${H5DIR}/include -I${ZDIR}/include' LDFLAGS='-L${H5DIR}/lib -L${ZDIR}/lib' ./configure --prefix=${NCDIR}
$ make check
$ make install # or sudo make install
~~~~
If you don't provide a `--prefix` option, installation will be in `/usr/local/`, in subdirectories lib/, include/, and bin/. The installation location specified with the `--prefix` option must be different from the source directory where the software is being built.
> WARNING: you should be able to use parallel 'make all'. But 'make check' will probably fail if you use parallel make. This is because historically, there are inter-dependencies between test programs. It is unlikely that this will be fixed any time soon, if ever.
Building netCDF with Classic Library Only {#build_classic}
---------------------------------------
It is possible to build the netCDF C libraries and utilities so that
only the netCDF classic and 64-bit offset formats are supported, or
the remote data access client is not built. (See \ref netcdf_format
for more information about the netCDF format variants. See the <a
href="http://www.opendap.org/documentation">DAP documentation and
support site</a> for more information about remote client access to
data on OPeNDAP servers.)
If necessary, set the NCDIR shell variable to indicate where netCDF should be
installed. Then to build a netCDF-3 library without support for the
netCDF-4 formats or functions, but with remote client access, use:
~~~~{.py}
$ # Build and install netCDF-3 from netCDF-4 source
$ ./configure --prefix=${NCDIR} --disable-netcdf-4
$ make check install
~~~~
To build with full support for netCDF-4 API's and format but without
remote client access, use:
~~~~{.py}
$ # Build and install netCDF-4 without DAP client support
$ ./configure --prefix=${NCDIR} --disable-dap
$ make check install
~~~~
To build without netCDF-4 support or remote client access, use:
~~~~{.py}
$ # Build and install minimal netCDF-3 with no DAP client support
$ ./configure --prefix=${NCDIR} --disable-netcdf-4 --disable-dap
$ make check install
~~~~
If you get the message that netCDF installed correctly, then you are
done!
Building with HDF4 Support {#build_hdf4}
---------------------
The netCDF-4 library can read HDF4 data files, if they were created
with the SD (Scientific Data) API.
For this to work, you must build the HDF4 library with the
configure option `--disable-netcdf`
to prevent it from building an HDF4 version of the netCDF-2 library
that conflicts with the netCDF-2 functions that are built into the Unidata
netCDF library.
Then, when building netCDF-4, use the `--enable-hdf4`
option to configure. The location for the HDF4 header files and
library must be specified in the CPPFLAGS and LDFLAGS environment variables
or configure options.
For HDF4 access to work, the library must be built with netCDF-4
features.
Here's an example, assuming the HDF5 library has been built and
installed in H5DIR and you will build and install the HDF4 library in
H4DIR (which could be the same as H5DIR). From the top-level HDF4
source directory:
~~~~{.py}
$ # Build and install HDF4
$ ./configure --enable-shared --disable-netcdf --disable-fortran --prefix=${H4DIR}
$ make check
$ make install
~~~~
Then from the top-level netCDF directory:
~~~~{.py}
$ # Build and install netCDF-4 with HDF4 access enabled
$ CPPFLAGS="-I${H5DIR}/include -I${H4DIR}/include" \
LDFLAGS="-L${H5DIR}/lib -L${H4DIR}/lib" \
./configure --enable-hdf4 --enable-hdf4-file-tests
$ make check
$ make install
~~~~
Building with Parallel I/O Support {#build_parallel}
--------------
For parallel I/O to work, HDF5 must be installed with
`--enable-parallel`, and an MPI library (and related libraries) must be
made available to the HDF5 configure. This can be accomplished with
an mpicc wrapper script.
The following works from the top-level HDF5 source directory to build
HDF5 with parallel I/O:
~~~~{.py}
$ # Build and install HDF5 with parallel support
$ CC=mpicc ./configure --enable-parallel --prefix=${H5DIR}
$ make check
$ make install
~~~~
If the HDF5 used by netCDF has been built with parallel I/O, then netCDF will also be built with inherited support for parallel I/O. This allows parallel I/O access to netCDF-4/HDF5 files. (See /ref netcdf_formats for more information about the netCDF format variants.)
From the top-level netCDF-4 source directory, the following builds netCDF-4 with parallel I/O, assuming H5DIR specifies where parallel HDF5 was installed:
~~~~{.py}
$ # Build, test, and install netCDF-4 with HDF5 parallel support
$ CC=mpicc CPPFLAGS=-I${H5DIR}/include LDFLAGS=-L${H5DIR}/lib \
./configure --disable-shared --enable-parallel-tests --prefix=${NCDIR}
$ make check
$ make install
~~~~
### Building PnetCDF from source {#build_pnetcdf_from_source}
To enable parallel I/O support for classic netCDF files, i.e. CDF-1, 2 and 5
formats, [PnetCDF library](https://parallel-netcdf.github.io) must also be
installed. First specify where you want to install PnetCDF in a shell
variable, for example PNDIR, and build it from the PnetCDF top-level source
directory. If you would like to build the shared library, include
`--enable-shared` option at the configure command line. By default, only a
static library is built.
~~~~{.py}
$ # Build and install PnetCDF
$ PNDIR=/usr/local
$ ./configure --prefix=${PNDIR} --with-mpi=/path/to/MPI/compilers
$ make check
$ make install # or sudo make install, if root permissions required
~~~~
To build netCDF-4 with PnetCDF support, from the top-level netCDF-4 source
directory, configure netCDF with the "--enable-pnetcdf" option. If PnetCDF
is built with static library only, add "--disable-shared" option.
~~~~{.py}
$ # Build, test, and install netCDF-4 with PnetCDF support
$ CC=mpicc CPPFLAGS="-I${H5DIR}/include -I${PNDIR}/include" \
LDFLAGS="-L${H5DIR}/lib -L${PNDIR}/lib" ./configure \
--enable-pnetcdf --enable-parallel-tests \
--prefix=${NCDIR}
$ make check
$ make install
~~~~
Linking to netCDF-C {#linking}
-------------------
For static builds of applications that use netCDF-4 you must link to all the
libraries, netCDF, HDF5, zlib, szip (if used with HDF5 build), PnetCDF (if used
with PnetCDF build), and curl (if the remote access client has not been
disabled). This will require -L options to your build for the locations of the
libraries, and -l (lower-case L) for the names of the libraries.
For example, you might build other applications with netCDF-4 by
setting the LIBS environment variable, assuming NCDIR, H5DIR, PNDIT, and ZDIR
indicate where netCDF, HDF5, PnetCDF, and zlib are installed:
~~~~{.py}
LIBS="-L${NCDIR}/lib -lnetcdf -L${H5DIR}/lib -lhdf5_hl -lhdf5 -L${PNDIR} -lpnetcdf -L${ZDIR}/lib -lz -lm"
~~~~
For shared builds, only `-L${NCDIR}/lib -lnetcdf` is
needed. All other libraries will be found automatically.
The `pkg-config` or `nc-config` utilities can be
used to specify build options for software that uses netCDF. For
example, to compile and link an application named myapp.c with a
netCDF-C libraries, whether shared or static, you can use
~~~~{.py}
$ cc -o myapp myapp.c `nc-config --cflags --libs`
~~~~
or
~~~~{.py}
$ PKG_CONFIG_PATH=${NCDIR}/lib/pkgconfig:$PKG_CONFIG_PATH
$ export PKG_CONFIG_PATH
$ cc -o myapp myapp.c `pkg-config --cflags --libs netcdf`
~~~~
configure options {#configure_options}
-----------------------------
These options are used for `autotools`-based builds.yup
Note: `--disable` prefix indicates that the option is normally enabled.
<table>
<tr><th>Option<th>Description<th>Dependencies
<tr><td>--disable-doxygen<td>Disable generation of documentation.<td>doxygen
<tr><td>--disable-fsync<td>disable fsync support<td>kernel fsync support
<tr><td>--disable-netcdf-4<td>build netcdf-3 without HDF5 and zlib<td>
<tr><td>--disable-netcdf4<td>synonym for disable-netcdf-4<td>
<tr><td>--enable-hdf4<td>build netcdf-4 with HDF4 read capability<td>HDF4, HDF5 and zlib
<tr><td>--enable-hdf4-file-tests<td>test ability to read HDF4 files<td>selected HDF4 files from Unidata ftp site
<tr><td>--disable-parallel4<td>build netcdf-4 without parallel I/O support<td>
<tr><td>--disable-cdf5<td>build netcdf-4 without support of classic CDF-5 file format<td>
<tr><td>--enable-pnetcdf<td>build netcdf-4 with parallel I/O for classic files (CDF-1, 2, and 5 formats) using PnetCDF<td>PnetCDF
<tr><td>--enable-extra-example-tests<td>Run extra example tests<td>--enable-netcdf-4,GNU sed
<tr><td>--disable-filter-testing<td>Run filter example<td>--enable-shared --enable-netcdf-4
<tr><td>--enable-parallel-tests <td>run extra parallel IO tests<td>--enable-netcdf-4 or --enable-pnetcdf, parallel IO support
<tr><td>--enable-logging<td>enable logging capability<td>--enable-netcdf-4
<tr><td>--disable-dap<td>build without DAP client support.<td>libcurl
<tr><td>--disable-dap-remote-tests<td>disable dap remote tests<td>--enable-dap
<tr><td>--enable-dap-long-tests<td>enable dap long tests<td>
<tr><td>--enable-extra-tests<td>run some extra tests that may not pass because of known issues<td>
<tr><td>--enable-ffio<td>use ffio instead of posixio (ex. on the Cray)<td>
<tr><td>--disable-examples<td>don't build the netCDF examples during make check
(examples are treated as extra tests by netCDF)<td>
<tr><td>--disable-v2<td>turn off the netCDF version 2 API<td>
<tr><td>--disable-utilities<td>don't build netCDF utilities ncgen, ncdump, and nccopy<td>
<tr><td>--disable-testsets<td>don't build or run netCDF tests<td>
<tr><td>--enable-large-file-tests <td>Run tests which create very large data
files<td>~13 GB disk space required, but recovered when
tests are complete). See option --with-temp-large to
specify temporary directory
<tr><td>--enable-benchmarks<td>Run benchmarks. This is an experimental feature.
The benchmarks are extra tests, used to check netCDF performance.
<td>sample data files from the Unidata ftp site
<tr><td>--disable-extreme-numbers
<td>don't use extreme numbers during testing, such as MAX_INT - 1<td>
<tr><td>--disable-shared<td>don't build shared libraries<td>
<tr><td>--disable-static<td>don't build static libraries<td>
<tr><td>--disable-largefile<td>omit support for files larger than 2GB<td>
<tr><td>--enable-mmap<td>Use mmap to implement NC_DISKLESS<td>System-provided `mmap` or `mremap` functions
<tr><td>--enable-valgrind-tests <td>build with valgrind-tests; static builds only<td>valgrind
</table>
Build Instructions for netCDF-C using CMake {#netCDF-CMake}
===========================================
## Overview {#cmake_overview}
Starting with netCDF-C 4.3.0, we are happy to announce the inclusion of CMake support. CMake will allow for building netCDF on a wider range of platforms, include Microsoft Windows with Visual Studio. CMake support also provides robust unit and regression testing tools. We will also maintain the standard autotools-based build system in parallel.
In addition to providing new build options for netCDF-C, we will also provide pre-built binary downloads for the shared versions of netCDF for use with Visual Studio.
## Requirements {#cmake_requirements}
The following packages are required to build netCDF-C using CMake.
* netCDF-C Source Code
* CMake version 2.8.12 or greater.
* Optional Requirements:
* HDF5 Libraries for netCDF4/HDF5 support.
* libcurl for DAP support.
* PnetCDF libraries for parallel I/O support to classic netCDF files
<center>
<img src="deptree.jpg" height="250px" />
</center>
## The CMake Build Process {#cmake_build}
There are four steps in the Build Process when using CMake
1. Configuration: Before compiling, the software is configured based on the desired options.
2. Building: Once configuration is complete, the libraries are compiled.
3. Testing: Post-build, it is possible to run tests to ensure the functionality of the netCDF-C libraries.
4. Installation: If all tests pass, the libraries can be installed in the location specified during configuration.
For users who prefer pre-built binaries, installation packages are available at \ref winbin
### Configuration {#cmake_configuration}
The output of the configuration step is a project file based on the appropriate configurator specified. Common configurators include:
* Unix Makefiles
* Visual Studio
* CodeBlocks
* ... and others
### Common CMake Options {#cmake_common_options}
| **Option** | **Autotools** | **CMake** |
| :------- | :---- | :----- |
Specify Install Location | --prefix=PREFIX | -D"CMAKE_INSTALL_PREFIX=PREFIX"
Enable/Disable netCDF-4 | --enable-netcdf-4<br>--disable-netcdf-4 | -D"ENABLE_NETCDF_4=ON" <br> -D"ENABLE_NETCDF_4=OFF"
Enable/Disable DAP | --enable-dap <br> --disable-dap | -D"ENABLE_DAP=ON" <br> -D"ENABLE_DAP=OFF"
Enable/Disable Utilities | --enable-utilities <br> --disable-utilities | -D"BUILD_UTILITIES=ON" <br> -D"BUILD_UTILITIES=OFF"
Specify shared/Static Libraries | --enable-shared <br> --enable-static | -D"BUILD_SHARED_LIBS=ON" <br> -D"BUILD_SHARED_LIBS=OFF"
Enable/Disable Parallel netCDF-4 | --enable-parallel4 <br> --disable-parallel4 | -D"ENABLE_PARALLEL4=ON" <br> -D"ENABLE_PARALLEL4=OFF"
Enable/Disable PnetCDF | --enable-pnetcdf<br>--disable-pnetcdf | -D"ENABLE_PNETCDF=ON" <br> -D"ENABLE_PNETCDF=OFF"
Enable/Disable CDF5 | --enable-cdf5 <br> --disable-cdf5 | -D"ENABLE_CDF5=ON" <br> -D"ENABLE_CDF5=OFF"
Enable/Disable Tests | --enable-testsets <br> --disable-testsets | -D"ENABLE_TESTS=ON" <br> -D"ENABLE_TESTS=OFF"
Enable/Disable Parallel Tests | --enable-parallel-tests<br> --disable-parallel-tests | -D"ENABLE_PARALLEL_TESTS=ON" <br> -D"ENABLE_PARALLEL_TESTS=OFF"
Specify a custom library location | Use *CFLAGS* and *LDFLAGS* | -D"CMAKE_PREFIX_PATH=/usr/custom_libs/"
A full list of *basic* options can be found by invoking `cmake [Source Directory] -L`. To enable a list of *basic* and *advanced* options, one would invoke `cmake [Source Directory] -LA`.
### Configuring your build from the command line. {#cmake_command_line}
The easiest configuration case would be one in which all of the dependent libraries are installed on the system path (in either Unix/Linux or Windows) and all the default options are desired. From the build directory (often, but not required to be located within the source directory):
> $ cmake [Source Directory]
If you have libraries installed in a custom directory, you may need to specify the **CMAKE\_PREFIX_PATH** variable to tell cmake where the libraries are installed. For example:
> $ cmake [Source Directory] -DCMAKE\_PREFIX\_PATH=/usr/custom_libraries/
## Building {#cmake_building}
The compiler can be executed directly with 'make' or the appropriate command for the configurator which was used.
> $ make
Building can also be executed indirectly via cmake:
> $ cmake --build [Build Directory]
## Testing {#cmake_testing}
Testing can be executed several different ways:
> $ make test
or
> $ ctest
or
> $ cmake --build [Build Directory] --target test
### Installation {#cmake_installation}
Once netCDF has been built and tested, it may be installed using the following commands:
> $ make install
or
> $ cmake --build [Build Directory] --target install
## See Also {#cmake_see_also}
For further information regarding netCDF and CMake, see \ref cmake_faq.

266
NUG/nug.tag Normal file
View File

@ -0,0 +1,266 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<tagfile>
<compound kind="file">
<name>bestpractices.md</name>
<path>/home/wfisher/Desktop/gitprojects/netcdf-c/NUG/</path>
<filename>bestpractices_8md</filename>
</compound>
<compound kind="file">
<name>DAP4.dox</name>
<path>/home/wfisher/Desktop/gitprojects/netcdf-c/NUG/</path>
<filename>_d_a_p4_8dox</filename>
</compound>
<compound kind="file">
<name>filters.md</name>
<path>/home/wfisher/Desktop/gitprojects/netcdf-c/NUG/</path>
<filename>filters_8md</filename>
</compound>
<compound kind="file">
<name>guide.md</name>
<path>/home/wfisher/Desktop/gitprojects/netcdf-c/NUG/</path>
<filename>guide_8md</filename>
</compound>
<compound kind="file">
<name>install.md</name>
<path>/home/wfisher/Desktop/gitprojects/netcdf-c/NUG/</path>
<filename>install_8md</filename>
</compound>
<compound kind="file">
<name>OPeNDAP.dox</name>
<path>/home/wfisher/Desktop/gitprojects/netcdf-c/NUG/</path>
<filename>_o_pe_n_d_a_p_8dox</filename>
</compound>
<compound kind="file">
<name>user_defined_formats.md</name>
<path>/home/wfisher/Desktop/gitprojects/netcdf-c/NUG/</path>
<filename>user__defined__formats_8md</filename>
</compound>
<compound kind="page">
<name>nug_netcdf_introduction</name>
<title>An Introduction to NetCDF</title>
<filename>nug_netcdf_introduction</filename>
<docanchor file="nug_netcdf_introduction" title="The netCDF Interface">nug_netcdf_interface</docanchor>
<docanchor file="nug_netcdf_introduction" title="The netCDF File Format">nug_netcdf_format</docanchor>
<docanchor file="nug_netcdf_introduction" title="How to Select the Format">nug_select_format</docanchor>
<docanchor file="nug_netcdf_introduction" title="NetCDF Classic Format (CDF-1)">nug_classic_format</docanchor>
<docanchor file="nug_netcdf_introduction" title="NetCDF 64-bit Offset Format (CDF-2)">nug_netcdf_64bit_offset_format</docanchor>
<docanchor file="nug_netcdf_introduction" title="NetCDF 64-bit Data Format (CDF-5)">nug_netcdf_64bit_data_format</docanchor>
<docanchor file="nug_netcdf_introduction" title="NetCDF-4 Format">nug_netcdf_4_format</docanchor>
<docanchor file="nug_netcdf_introduction" title="NetCDF Library Architecture">nug_architecture</docanchor>
<docanchor file="nug_netcdf_introduction" title="What about Performance?">nug_performance</docanchor>
<docanchor file="nug_netcdf_introduction" title="Creating Self-Describing Data conforming to Conventions">nug_creating_self</docanchor>
<docanchor file="nug_netcdf_introduction" title="Limitations of netCDF">nug_limitations</docanchor>
</compound>
<compound kind="page">
<name>nug_netcdf_data_set_components</name>
<title>The Components of a NetCDF Data Set</title>
<filename>nug_netcdf_data_set_components</filename>
<docanchor file="nug_netcdf_data_set_components" title="The Data Model">nug_data_model</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Data Model in NetCDF-4/HDF5 Files">nug_Enhanced</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Dimensions">nug_dimensions</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Variables">nug_variables</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Coordinate Variables">nug_coordinate_variables</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Attributes">nug_attributes</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Differences between Attributes and Variables">nug_differences_atts_vars</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="NetCDF Names">nug_object_name</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Characters in NetCDF Names">nug_Permitted</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Length">nug_Name</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Conventions">nug_NetCDF</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Is NetCDF a Good Archive Format?">nug_archival</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Background and Evolution of the NetCDF Interface">nug_background</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="The Remote Data Access Client">nug_remote_client</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Data Access">nug_data_access</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="Forms of Data Access">nug_forms_of_data_access</docanchor>
<docanchor file="nug_netcdf_data_set_components" title="A C Example of Array-Section Access">nug_c_array_section_access</docanchor>
</compound>
<compound kind="page">
<name>nug_file_structure_and_performance</name>
<title>File Structure and Performance</title>
<filename>nug_file_structure_and_performance</filename>
<docanchor file="nug_file_structure_and_performance" title="Parts of a NetCDF Classic File">nug_classic_file_parts</docanchor>
<docanchor file="nug_file_structure_and_performance" title="Parts of a NetCDF-4 HDF5 File">nug_parts_of_netcdf4</docanchor>
<docanchor file="nug_file_structure_and_performance" title="The Extended XDR Layer">nug_xdr_layer</docanchor>
<docanchor file="nug_file_structure_and_performance" title="Large File Support">nug_large_file_support</docanchor>
<docanchor file="nug_file_structure_and_performance" title="NetCDF 64-bit Offset Format Limitations">nug_offset_format_limitations</docanchor>
<docanchor file="nug_file_structure_and_performance" title="NetCDF Classic Format Limitations">nug_classic_format_limitations</docanchor>
<docanchor file="nug_file_structure_and_performance" title="The NetCDF-3 I/O Layer">nug_netcdf_3_io</docanchor>
<docanchor file="nug_file_structure_and_performance" title="Parallel Access with NetCDF-4">nug_parallel_access</docanchor>
<docanchor file="nug_file_structure_and_performance" title="Interoperability with HDF5">nug_interoperability_with_hdf5</docanchor>
</compound>
<compound kind="page">
<name>nug_netcdf_perf_chunking</name>
<title>Improving Performance with Chunking</title>
<filename>nug_netcdf_perf_chunking</filename>
<docanchor file="nug_netcdf_perf_chunking" title="The Chunk Cache">nug_chunk_cache</docanchor>
<docanchor file="nug_netcdf_perf_chunking" title="The Default Chunking Scheme">nug_default_chunking_4_1</docanchor>
<docanchor file="nug_netcdf_perf_chunking" title="Chunking and Parallel I/O">nug_chunking_parallel_io</docanchor>
<docanchor file="nug_netcdf_perf_chunking" title="A Utility to Help Benchmark Results: bm_file">nug_bm_file</docanchor>
</compound>
<compound kind="page">
<name>nug_netcdf_utilities_guide</name>
<title>NetCDF Utilities</title>
<filename>nug_netcdf_utilities_guide</filename>
<docanchor file="nug_netcdf_utilities_guide" title="CDL Guide">nug_cdl_guide</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="CDL Syntax">nug_cdl_syntax</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="CDL Data Types">nug_cdl_data_types</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="CDL Notation for Data Constants">nug_cdl_constants</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="ncdump">nug_ncdump_guide</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="ncdump synopsis">nug_ncdump_SYNOPSIS</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="ncdump description">nug_ncdump_DESCRIPTION</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="ncdump options">nug_ncdump_OPTIONS</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="ncdump examples">nug_ncdump_EXAMPLES</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="SEE ALSO">nug_see_also_ncdump</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="NOTE ON STRING OUTPUT">nug_ncdump_string_note</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="nccopy">nug_guide_nccopy</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="nccopy synopsis">nug_nccopy_SYNOPSIS</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="nccopy description">nug_nccopy_DESCRIPTION</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="nccopy options">nug_nccopy_OPTIONS</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="nccopy examples">nug_nccopy_EXAMPLES</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="SEE ALSO">nug_see_also_nccopy</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="ncgen">nug_guide_ncgen</docanchor>
<docanchor file="nug_netcdf_utilities_guide" title="ncgen3">nug_guide_ncgen3</docanchor>
</compound>
<compound kind="page">
<name>nug_users_guide_appendices</name>
<title>Appendices</title>
<filename>nug_users_guide_appendices</filename>
</compound>
<compound kind="page">
<name>BestPractices</name>
<title>Writing NetCDF Files: Best Practices</title>
<filename>_best_practices</filename>
<docanchor file="_best_practices" title="Best Practices ">bp_Best_Practices</docanchor>
<docanchor file="_best_practices" title="Conventions">bp_Conventions</docanchor>
<docanchor file="_best_practices" title="Coordinate Systems">bp_Coordinate-Systems</docanchor>
<docanchor file="_best_practices" title="Variable Grouping">bp_Variable-Grouping</docanchor>
<docanchor file="_best_practices" title="Variable Attributes">bp_Variable-Attributes</docanchor>
<docanchor file="_best_practices" title="Strings and Variables of type char">bp_Strings-and-Variables-of-type-char</docanchor>
<docanchor file="_best_practices" title="Calendar Date/Time">bp_Calendar-Date-Time</docanchor>
<docanchor file="_best_practices" title="Unsigned Data">bp_Unsigned-Data</docanchor>
<docanchor file="_best_practices" title="Packed Data Values">bp_Packed-Data-Values</docanchor>
<docanchor file="_best_practices" title="Missing Data Values">bp_Missing-Data-Values</docanchor>
<docanchor file="_best_practices" title="Miscellaneous tips">bp_Miscellaneous-tips</docanchor>
<docanchor file="_best_practices" title="Spelling netCDF: Best Practices">bp_Spelling-netCDF-Best-Practices</docanchor>
</compound>
<compound kind="page">
<name>getting_and_building_netcdf</name>
<title>Getting and Building netCDF</title>
<filename>getting_and_building_netcdf</filename>
<docanchor file="getting_and_building_netcdf" title="Getting netCDF-C ">getting</docanchor>
<docanchor file="getting_and_building_netcdf" title="Getting pre-built netCDF-C libraries. ">sec_get_pre_built</docanchor>
<docanchor file="getting_and_building_netcdf" title="Getting the latest netCDF-C Source Code ">sec_get_source</docanchor>
<docanchor file="getting_and_building_netcdf" title="The latest release">sec_latest_release</docanchor>
<docanchor file="getting_and_building_netcdf" title="The developer snapshot">sec_dev_snapshot</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building netCDF-C ">building</docanchor>
<docanchor file="getting_and_building_netcdf" title="Requirements ">netcdf_requirements</docanchor>
<docanchor file="getting_and_building_netcdf" title="CMake and Windows support ">sub</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building with netCDF-4 and the Remote Data Client ">build_default</docanchor>
<docanchor file="getting_and_building_netcdf" title="Optional: szip support">op_szip_support</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building zlib from source">build_zlib_from_source</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building hdf5 from source">build_hdf5_from_source</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building netCDF-4 and the Remote Data Client from source">build_nc4_dap_from_source</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building netCDF with Classic Library Only ">build_classic</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building with HDF4 Support ">build_hdf4</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building with Parallel I/O Support ">build_parallel</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building PnetCDF from source">build_pnetcdf_from_source</docanchor>
<docanchor file="getting_and_building_netcdf" title="Linking to netCDF-C ">linking</docanchor>
<docanchor file="getting_and_building_netcdf" title="configure options ">configure_options</docanchor>
<docanchor file="getting_and_building_netcdf" title="Build Instructions for netCDF-C using CMake ">netCDF-CMake</docanchor>
<docanchor file="getting_and_building_netcdf" title="Overview">cmake_overview</docanchor>
<docanchor file="getting_and_building_netcdf" title="Requirements">cmake_requirements</docanchor>
<docanchor file="getting_and_building_netcdf" title="The CMake Build Process">cmake_build</docanchor>
<docanchor file="getting_and_building_netcdf" title="Configuration">cmake_configuration</docanchor>
<docanchor file="getting_and_building_netcdf" title="Common CMake Options">cmake_common_options</docanchor>
<docanchor file="getting_and_building_netcdf" title="Configuring your build from the command line.">cmake_command_line</docanchor>
<docanchor file="getting_and_building_netcdf" title="Building">cmake_building</docanchor>
<docanchor file="getting_and_building_netcdf" title="Testing">cmake_testing</docanchor>
<docanchor file="getting_and_building_netcdf" title="Installation">cmake_installation</docanchor>
<docanchor file="getting_and_building_netcdf" title="See Also">cmake_see_also</docanchor>
</compound>
<compound kind="page">
<name>dap4</name>
<title>DAP4 Protocol Support</title>
<filename>dap4</filename>
<docanchor file="dap4" title="DAP4 Introduction">dap4_introduction</docanchor>
<docanchor file="dap4" title="Accessing Data Using the DAP4 Prototocol">dap4_accessing_data</docanchor>
<docanchor file="dap4" title="Defined Client Parameters">dap4_defined_params</docanchor>
<docanchor file="dap4" title="Notes on Debugging DAP4 Access">dap4_debug</docanchor>
<docanchor file="dap4" title="HTTP Configuration.">dap4_http2_config</docanchor>
<docanchor file="dap4" title="Point of Contact">dap4_poc</docanchor>
</compound>
<compound kind="page">
<name>dap2</name>
<title>DAP2 Support</title>
<filename>dap2</filename>
<docanchor file="dap2" title="DAP2 (OPeNDAP) Introduction">dap_introduction</docanchor>
<docanchor file="dap2" title="OPeNDAP Documentation">dap_dap_information</docanchor>
<docanchor file="dap2" title="Accessing OPeNDAP Data">dap_accessing_data</docanchor>
<docanchor file="dap2" title="DAP to NetCDF Translation Rules">dap_to_netcdf</docanchor>
<docanchor file="dap2" title="netCDF-3 Translation Rules">nc3_trans_rules</docanchor>
<docanchor file="dap2" title="Variable Definition">var_def</docanchor>
<docanchor file="dap2" title="DAP2 Reserved Keywords">dap2_reserved_keywords</docanchor>
<docanchor file="dap2" title="Variable Dimension Translation">var_dim_trans</docanchor>
<docanchor file="dap2" title="Dimension translation">dim_trans</docanchor>
<docanchor file="dap2" title="Variable Name Translation">var_name_trans</docanchor>
<docanchor file="dap2" title="Translating DAP DDS Sequences">dap_translation</docanchor>
<docanchor file="dap2" title="Caching">dap_caching</docanchor>
<docanchor file="dap2" title="Defined Client Parameters">dap_defined_params</docanchor>
<docanchor file="dap2" title="Notes on Debugging OPeNDAP Access">dap_debug</docanchor>
<docanchor file="dap2" title="HTTP Configuration.">http_config</docanchor>
</compound>
<compound kind="page">
<name>user_defined_formats</name>
<title>User-Defined Formats for NetCDF</title>
<filename>user_defined_formats</filename>
<docanchor file="user_defined_formats" title="User-Defined Formats ">udf_user_defined_formats</docanchor>
<docanchor file="user_defined_formats" title="Introduction">udf_Introduction</docanchor>
<docanchor file="user_defined_formats" title="Magic Numbers">autotoc_md1</docanchor>
<docanchor file="user_defined_formats" title="Using User-Defined Formats from C Programs">udf_With_C</docanchor>
<docanchor file="user_defined_formats" title="Building NetCDF C Library with a User-Defined Format Library">udf_Build_NetCDF_With_UDF</docanchor>
<docanchor file="user_defined_formats" title="Creating a User-Defined Format">udf_Create_UDF</docanchor>
<docanchor file="user_defined_formats" title="Read-Only User-Defined Formats">autotoc_md2</docanchor>
<docanchor file="user_defined_formats" title="Examples">udf_Examples</docanchor>
</compound>
<compound kind="page">
<name>md_filters</name>
<title>NetCDF-4 Filter Support</title>
<filename>md_filters</filename>
<docanchor file="md_filters" title="NetCDF-4 Filter Support ">filters</docanchor>
<docanchor file="md_filters" title="Introduction">filters_intro</docanchor>
<docanchor file="md_filters" title="Enabling A Compression Filter">filters_enable</docanchor>
<docanchor file="md_filters" title="Using The API">filters_API</docanchor>
<docanchor file="md_filters" title="Using ncgen">filters_NCGEN</docanchor>
<docanchor file="md_filters" title="Example CDL File (Data elided)">autotoc_md3</docanchor>
<docanchor file="md_filters" title="Using nccopy">filters_NCCOPY</docanchor>
<docanchor file="md_filters" title="Parameter Encode/Decode">filters_paramcoding</docanchor>
<docanchor file="md_filters" title="Encoding Algorithms">autotoc_md4</docanchor>
<docanchor file="md_filters" title="Encoding">autotoc_md5</docanchor>
<docanchor file="md_filters" title="Decoding">autotoc_md6</docanchor>
<docanchor file="md_filters" title="Filter Specification Syntax">filters_syntax</docanchor>
<docanchor file="md_filters" title="Dynamic Loading Process ">filters_Process</docanchor>
<docanchor file="md_filters" title="Plugin directory ">filters_Plugindir</docanchor>
<docanchor file="md_filters" title="Plugin Library Naming ">filters_Pluginlib</docanchor>
<docanchor file="md_filters" title="Plugin Verification ">filters_Pluginverify</docanchor>
<docanchor file="md_filters" title="Debugging ">filters_Debug</docanchor>
<docanchor file="md_filters" title="Test Case ">filters_TestCase</docanchor>
<docanchor file="md_filters" title="Example ">filters_Example</docanchor>
<docanchor file="md_filters" title="Notes">autotoc_md7</docanchor>
<docanchor file="md_filters" title="Memory Allocation Issues">autotoc_md8</docanchor>
<docanchor file="md_filters" title="SZIP Issues">autotoc_md9</docanchor>
<docanchor file="md_filters" title="Supported Systems">autotoc_md10</docanchor>
<docanchor file="md_filters" title="Generic Plugin Build">autotoc_md11</docanchor>
<docanchor file="md_filters" title="Appendix A. Support Utilities ">filters_AppendixA</docanchor>
<docanchor file="md_filters" title="Appendix B. Programmatic Filter Definition ">filters_programmatic</docanchor>
<docanchor file="md_filters" title="API Concepts">autotoc_md12</docanchor>
<docanchor file="md_filters" title="NetCDF API">autotoc_md13</docanchor>
<docanchor file="md_filters" title="Example">autotoc_md14</docanchor>
<docanchor file="md_filters" title="References">filters_References</docanchor>
<docanchor file="md_filters" title="Point of Contact">autotoc_md15</docanchor>
</compound>
<compound kind="page">
<name>index</name>
<title></title>
<filename>index</filename>
<docanchor file="index" title="The Purpose of NetCDF">autotoc_md0</docanchor>
</compound>
</tagfile>

304
NUG/types.dox Normal file
View File

@ -0,0 +1,304 @@
/** \file types.dox Documentation related to NetCDF Types
Documentation of types.
\page data_type Data Types
\tableofcontents
Data in a netCDF file may be one of the \ref external_types, or may be
a user-defined data type (see \ref user_defined_types).
\section external_types External Data Types
The atomic external types supported by the netCDF interface are:
- ::NC_BYTE 8-bit signed integer
- ::NC_UBYTE 8-bit unsigned integer *
- ::NC_CHAR 8-bit character
- ::NC_SHORT 16-bit signed integer
- ::NC_USHORT 16-bit unsigned integer *
- ::NC_INT (or ::NC_LONG) 32-bit signed integer
- ::NC_UINT 32-bit unsigned integer *
- ::NC_INT64 64-bit signed integer *
- ::NC_UINT64 64-bit unsigned integer *
- ::NC_FLOAT 32-bit floating point
- ::NC_DOUBLE 64-bit floating point
- ::NC_STRING variable length character string +
\remark * These types are available only for CDF5 (NC_CDF5) and netCDF-4 format (NC_NETCDF4) files. All the unsigned ints and the 64-bit ints are for CDF5 or netCDF-4 files only.
\remark + These types are available only for netCDF-4 (NC_NETCDF4) files.
These types were chosen to provide a reasonably wide range of
trade-offs between data precision and number of bits required for each
value. These external data types are independent from whatever
internal data types are supported by a particular machine and language
combination.
These types are called "external", because they correspond to the
portable external representation for netCDF data. When a program reads
external netCDF data into an internal variable, the data is converted,
if necessary, into the specified internal type. Similarly, if you
write internal data into a netCDF variable, this may cause it to be
converted to a different external type, if the external type for the
netCDF variable differs from the internal type.
The separation of external and internal types and automatic type
conversion have several advantages. You need not be aware of the
external type of numeric variables, since automatic conversion to or
from any desired numeric type is available. You can use this feature
to simplify code, by making it independent of external types, using a
sufficiently wide internal type, e.g., double precision, for numeric
netCDF data of several different external types. Programs need not be
changed to accommodate a change to the external type of a variable.
If conversion to or from an external numeric type is necessary, it is
handled by the library.
Converting from one numeric type to another may result in an error if
the target type is not capable of representing the converted
value. For example, an internal short integer type may not be able to
hold data stored externally as an integer. When accessing an array of
values, a range error is returned if one or more values are out of the
range of representable values, but other values are converted
properly.
Note that mere loss of precision in type conversion does not return an
error. Thus, if you read double precision values into a
single-precision floating-point variable, for example, no error
results unless the magnitude of the double precision value exceeds the
representable range of single-precision floating point numbers on your
platform. Similarly, if you read a large integer into a float
incapable of representing all the bits of the integer in its mantissa,
this loss of precision will not result in an error. If you want to
avoid such precision loss, check the external types of the variables
you access to make sure you use an internal type that has adequate
precision.
The names for the primitive external data types (char, byte, ubyte, short,
ushort, int, uint, int64, uint64, float or real, double, string) are
reserved words in CDL, so the names of variables, dimensions, and
attributes must not be type names.
It is possible to interpret byte data as either signed (-128 to 127)
or unsigned (0 to 255). However, when reading byte data to be
converted into other numeric types, it is interpreted as signed.
For the correspondence between netCDF external data types and the data
types of a language see \ref variables.
\section classic_structures Data Structures in Classic Files
The only kind of data structure directly supported by the netCDF
classic abstraction, i.e. CDF-1, 2, and 5 formats, is a collection of named
arrays with attached vector attributes. NetCDF is not particularly
well-suited for storing linked lists, trees, sparse matrices, ragged
arrays or other kinds of data structures requiring pointers.
It is possible to build other kinds of data structures in netCDF
classic formats, from sets of arrays by adopting
various conventions regarding the use of data in one array as pointers
into another array. The netCDF library won't provide much help or
hindrance with constructing such data structures, but netCDF provides
the mechanisms with which such conventions can be designed.
The following netCDF classic example stores a ragged array ragged_mat
using an attribute row_index to name an associated index variable
giving the index of the start of each row. In this example, the first
row contains 12 elements, the second row contains 7 elements (19 -
12), and so on. (NetCDF-4 includes native support for variable length
arrays. See below.)
\code
float ragged_mat(max_elements);
ragged_mat:row_index = "row_start";
int row_start(max_rows);
data:
row_start = 0, 12, 19, ...
\endcode
As another example, netCDF variables may be grouped within a netCDF
classic dataset by defining attributes that list the
names of the variables in each group, separated by a conventional
delimiter such as a space or comma. Using a naming convention for
attribute names for such groupings permits any number of named groups
of variables. A particular conventional attribute for each variable
might list the names of the groups of which it is a member. Use of
attributes, or variables that refer to other attributes or variables,
provides a flexible mechanism for representing some kinds of complex
structures in netCDF datasets.
\section nc4_user_defined_types NetCDF-4 User Defined Data Types
NetCDF supported six data types through version 3.6.0 (char, byte,
short, int, float, and double). Starting with version 4.0, many new
data types are supported (unsigned int types, strings, compound types,
variable length arrays, enums, opaque).
In addition to the new atomic types the user may define types.
Types are defined in define mode, and must be fully defined before
they are used. New types may be added to a file by re-entering define
mode.
Once defined the type may be used to create a variable or attribute.
Types may be nested in complex ways. For example, a compound type
containing an array of VLEN types, each containing variable length
arrays of some other compound type, etc. Users are cautioned to keep
types simple. Reading data of complex types can be challenging for
Fortran users.
Types may be defined in any group in the data file, but they are
always available globally in the file.
Types cannot have attributes (but variables of the type may have
attributes).
Only files created with the netCDF-4/HDF5 mode flag (::NC_NETCDF4) but
without the classic model flag (::NC_CLASSIC_MODEL) may use
user-defined types or the new atomic data types.
Once types are defined, use their ID like any other type ID when
defining variables or attributes. Use functions
- nc_put_att() / nc_get_att()
- nc_put_var() / nc_get_var()
- nc_put_var1() / nc_get_var1()
- nc_put_vara() / nc_get_vara()
- nc_put_vars() / nc_get_vars()
functions to access attribute and variable data of user defined type.
\subsection types_compound_types Compound Types
Compound types allow the user to combine atomic and user-defined types
into C-like structs. Since users defined types may be used within a
compound type, they can contain nested compound types.
Users define a compound type, and (in their C code) a corresponding C
struct. They can then use nc_put_vara() and related functions to write
multi-dimensional arrays of these structs, and nc_get_vara() calls
to read them.
While structs, in general, are not portable from platform to platform,
the HDF5 layer (when installed) performs the magic required to figure
out your platform's idiosyncrasies, and adjust to them. The end result
is that HDF5 compound types (and therefore, netCDF-4 compound types),
are portable.
For more information on creating and using compound types, see
Compound Types in The NetCDF C Interface Guide.
\subsection vlen_types VLEN Types
Variable length arrays can be used to create a ragged array of data,
in which one of the dimensions varies in size from point to point.
An example of VLEN use would the to store a 1-D array of dropsonde
data, in which the data at each drop point is of variable length.
There is no special restriction on the dimensionality of VLEN
variables. It's possible to have 2D, 3D, 4D, etc. data, in which each
point contains a VLEN.
A VLEN has a base type (that is, the type that it is a VLEN of). This
may be one of the atomic types (forming, for example, a variable
length array of ::NC_INT), or it can be another user defined type,
like a compound type.
With VLEN data, special memory allocation and deallocation procedures
must be followed, or memory leaks may occur.
Compression is permitted but may not be effective for VLEN data,
because the compression is applied to structures containing lengths
and pointers to the data, rather than the actual data.
For more information on creating and using variable length arrays, see
Variable Length Arrays in The NetCDF C Interface Guide.
\subsection types_opaque_types Opaque Types
Opaque types allow the user to store arrays of data blobs of a fixed size.
For more information on creating and using opaque types, see Opaque
Type in The NetCDF C Interface Guide.
\subsection enum_types Enum Types
Enum types allow the user to specify an enumeration.
For more information on creating and using enum types, see Enum Type
in The NetCDF C Interface Guide.
\section type_conversion Type Conversion
Each netCDF variable has an external type, specified when the variable
is first defined. This external type determines whether the data is
intended for text or numeric values, and if numeric, the range and
precision of numeric values.
If the netCDF external type for a variable is char, only character
data representing text strings can be written to or read from the
variable. No automatic conversion of text data to a different
representation is supported.
If the type is numeric, however, the netCDF library allows you to
access the variable data as a different type and provides automatic
conversion between the numeric data in memory and the data in the
netCDF variable. For example, if you write a program that deals with
all numeric data as double-precision floating point values, you can
read netCDF data into double-precision arrays without knowing or
caring what the external type of the netCDF variables are. On reading
netCDF data, integers of various sizes and single-precision
floating-point values will all be converted to double-precision, if
you use the data access interface for double-precision values. Of
course, you can avoid automatic numeric conversion by using the netCDF
interface for a value type that corresponds to the external data type
of each netCDF variable, where such value types exist.
The automatic numeric conversions performed by netCDF are easy to
understand, because they behave just like assignment of data of one
type to a variable of a different type. For example, if you read
floating-point netCDF data as integers, the result is truncated
towards zero, just as it would be if you assigned a floating-point
value to an integer variable. Such truncation is an example of the
loss of precision that can occur in numeric conversions.
Converting from one numeric type to another may result in an error if
the target type is not capable of representing the converted
value. For example, an integer may not be able to hold data stored
externally as an IEEE floating-point number. When accessing an array
of values, a range error is returned if one or more values are out of
the range of representable values, but other values are converted
properly.
Note that mere loss of precision in type conversion does not result in
an error. For example, if you read double precision values into an
integer, no error results unless the magnitude of the double precision
value exceeds the representable range of integers on your
platform. Similarly, if you read a large integer into a float
incapable of representing all the bits of the integer in its mantissa,
this loss of precision will not result in an error. If you want to
avoid such precision loss, check the external types of the variables
you access to make sure you use an internal type that has a compatible
precision.
Whether a range error occurs in writing a large floating-point value
near the boundary of representable values may be depend on the
platform. The largest floating-point value you can write to a netCDF
float variable is the largest floating-point number representable on
your system that is less than 2 to the 128th power. The largest double
precision value you can write to a double variable is the largest
double-precision number representable on your system that is less than
2 to the 1024th power.
The _uchar and _schar functions were introduced in netCDF-3 to
eliminate an ambiguity, and support both signed and unsigned byte data.
In netCDF-2, whether the external NC_BYTE type represented signed or
unsigned values was left up to the user. In netcdf-3, we treat NC_BYTE
as signed for the purposes of conversion to short, int, long, float, or
double. (Of course, no conversion takes place when the internal type is
signed char.) In the _uchar functions, we treat NC_BYTE as if it were
unsigned. Thus, no NC_ERANGE error can occur converting between NC_BYTE
and unsigned char.
*/

113
NUG/user_defined_formats.md Normal file
View File

@ -0,0 +1,113 @@
User-Defined Formats for NetCDF {#user_defined_formats}
===============================
[TOC]
User-Defined Formats {#udf_user_defined_formats}
=====================================
## Introduction {#udf_Introduction}
User-defined formats allow users to write their own adaptors for the
netCDF C library, so that it can read and (optionally) write a
proprietary format through the netCDF API.
This capability is currently experimental. It involves the exposing of internal
netcdf interfaces and data structures that were previously invisible to users.
This means that it is unstable and the exposed interfaces are subject to change.
Use with caution.
User-defined format code is packaged into a separate library, the
user-defined format dispatch library. This library, when linked with
the netCDF library, will allow user programs to read their proprietary
format through the netCDF API. The proprietary format is treated as if
it were one of the netCDF C library native binary formats.
Coding the user-defined format dispatch library requires knowledge of
the netCDF library internals. User-defined format dispatch libraries
must be written in C.
### Magic Numbers
Some file formats use the first few bytes of the file as an identifier
for format. For example, HDF5 files have "HDF5" as the fist 4 bytes,
and netCDF classic files have "CDF1" as the first four bytes. This is
called the "magic number" of the file.
User-defined formats can optionally support magic numbers. If the
user-defined format uses a magic number, and that magic number is
associated with the user-defined format, then netCDF will be able to
correctly identify those files from nc_open(). It will not be
necessary for the user to know or specify the underlying format.
## Using User-Defined Formats from C Programs {#udf_With_C}
A user-defined format can be added dynamically in the case of C programs.
```
/* Add our test user defined format. */
if (nc_def_user_format(NC_UDF0, &tst_dispatcher, NULL)) ERR;
```
The file can now be opened by netCDF:
```
if (nc_open(FILE_NAME, NC_UDF0, &ncid)) ERR;
```
If a magic number is used in the file, that may be passed to
nc_def_user_format(). In that case, specifying the NC_UDF0 mode flag
to nc_open() is optional. The nc_open() will check the file and find
the magic number, and automatically associate the file with
NC_UDF0. The user will not need to know the format in order to open
the file with nc_open().
## Building NetCDF C Library with a User-Defined Format Library {#udf_Build_NetCDF_With_UDF}
Once a user-defined format library is created, it may built into a
netCDF install. This allows the netCDF Fortran APIs, and the netCDF
utilities (ncdump, ncgen, nccopy) to natively use the user-defined
format.
First the user-defined dispatch library must be built and installed.
Then the netcdf-c package must be (re-)built. When building netcdf-c,
add the location of the user-defined format dispatch library include
file to the CPPFLAGS, and the location of the user-defined format
dispatch library in LDFLAGS.
Configure netcdf-c with the option ````--with-udf0=<udf_lib_name>````.
If a magic number is associated with the user-defined format, it can
be specified with the --with-udf0-magic-number= argument.
## Creating a User-Defined Format {#udf_Create_UDF}
Creators of user-defined format libraries will have to become familiar
with the internals of the netCDF-4 code.
### Read-Only User-Defined Formats
Many users will find that a read-only user-defined formats meets most
of their needs. With a read-only user-defined format, netCDF will be
able to read files of the user-defined format. Tools like ncdump and
nccopy can work on the files.
A read-only user-defined format can be implemented with only 6
functions. The code in libhdf4 is an excellent example of a read-only
dispatch layer.
## Examples {#udf_Examples}
The most simple-case example of a user-defined format is provided in
test nc_test4/tst_udf.c.
A slightly more complex example, including the required
autoconf/automake files to build a user-defined format library, can be
found at the [sample user-defined format
library](https://github.com/NOAA-GSD/sample-netcdf-dispatch). In this
example, the HDF4 SD reader is re-implemented as an external
user-defined format. (This is unnecessary if you just want to read
HDF4 SD files, since the netCDF C library already includes an HDF4 SD
file reader. This user-defined format library uses the same code. It
is repackaged as a user-defined library to provide a working sample.)