NCDatasets allows one to read and create netCDF files.
NetCDF data set and attribute list behave like Julia dictionaries and variables like Julia arrays.
NCDatasets provides support for the following netCDF CF conventions:
_FillValuewill be returned as
add_offsetare applied if present
- time variables (recognized by the
unitsattribute) are returned as
- Support of the CF calendars (standard, gregorian, proleptic gregorian, julian, all leap, no leap, 360 day)
- The raw data can also be accessed (without the transformations above).
- Contiguous ragged array representation
Other features include:
- Support for NetCDF 4 compression and variable-length arrays (i.e. arrays of vectors where each vector can have potentailly a different length)
- The module also includes an utility function
ncgenwhich generates the Julia code that would produce a netCDF file with the same metadata as a template netCDF file.
Inside the Julia shell, you can download and install the package by issuing:
using Pkg Pkg.add("NCDatasets")
- Explore the content of a netCDF file
- Load a netCDF file
- Create a netCDF file
- Edit an existing netCDF file
Explore the content of a netCDF file
Before reading the data from a netCDF file, it is often useful to explore the list of variables and attributes defined in it.
For interactive use, the following commands (without ending semicolon) display the content of the file similarly to
ncdump -h file.nc:
using NCDatasets ds = Dataset("file.nc")
This creates the central structure of NCDatasets.jl,
Dataset, which represents the contents of the netCDF file (without immediatelly loading everything in memory).
NCDataset is an alias for
The following displays the information just for the variable
while to get the global attributes you can do:
which produces a listing like:
Dataset: file.nc Group: / Dimensions time = 115 Variables time (115) Datatype: Float64 Dimensions: time Attributes: calendar = gregorian standard_name = time units = days since 1950-01-01 00:00:00 [...]
Load a netCDF file
Loading a variable with known structure can be achieved by accessing the variables and attributes directly by their name.
# The mode "r" stands for read-only. The mode "r" is the default mode and the parameter can be omitted. ds = Dataset("/tmp/test.nc","r") v = ds["temperature"] # load a subset subdata = v[10:30,30:5:end] # load all data data = v[:,:] # load all data ignoring attributes like scale_factor, add_offset, _FillValue and time units data2 = v.var[:,:] # load an attribute unit = v.attrib["units"] close(ds)
In the example above, the subset can also be loaded with:
subdata = Dataset("/tmp/test.nc")["temperature"][10:30,30:5:end]
This might be useful in an interactive session. However, the file
test.nc is not closed, which can be a problem if you open many files. On Linux the number of opened files is often limited to 1024 (soft limit). If you write to a file, you should also always close the file to make sure that the data is properly written to the disk.
An alternative way to ensure the file has been closed is to use a
do block: the file will be closed automatically when leaving the block.
data = Dataset(filename,"r") do ds ds["temperature"][:,:] end # ds is closed
Create a netCDF file
The following gives an example of how to create a netCDF file by defining dimensions, variables and attributes.
using NCDatasets using DataStructures # This creates a new NetCDF file /tmp/test.nc. # The mode "c" stands for creating a new file (clobber) ds = Dataset("/tmp/test.nc","c") # Define the dimension "lon" and "lat" with the size 100 and 110 resp. defDim(ds,"lon",100) defDim(ds,"lat",110) # Define a global attribute ds.attrib["title"] = "this is a test file" # Define the variables temperature with the attribute units v = defVar(ds,"temperature",Float32,("lon","lat"), attrib = OrderedDict( "units" => "degree Celsius")) # add additional attributes v.attrib["comments"] = "this is a string attribute with Unicode Ω ∈ ∑ ∫ f(x) dx" # Generate some example data data = [Float32(i+j) for i = 1:100, j = 1:110] # write a single column v[:,1] = data[:,1] # write a the complete data set v[:,:] = data close(ds)
Edit an existing netCDF file
When you need to modify the variables or the attributes of a netCDF, you have
to open it with the
"a" option. Here of instance we add a global attribute creator to the
file created in the previous step.
ds = Dataset("/tmp/test.nc","a") ds.attrib["creator"] = "your name" close(ds);
The benchmark loads a variable of the size 1000x500x100 in slices of 1000x500 (applying the scaling of the CF conventions) and computes the maximum of each slice and the average of each maximum over all slices. This operation is repeated 100 times. The code is available at https://github.com/Alexander-Barth/NCDatasets.jl/tree/master/test/perf .
All runtimes are in seconds. Julia 1.3.1 (with NCDatasets 0667438), R 3.4.4 (with ncdf4 1.17) and python 3.6.9 (with netCDF4 1.4.2). This CPU is a i7-7700.
Filing an issue
When you file an issue, please include sufficient information that would allow somebody else to reproduce the issue, in particular:
- Provide the code that generates the issue.
- If necessary to run your code, provide the used netCDF file(s).
- Make your code and netCDF file(s) as simple as possible (while still showing the error and being runnable). A big thank you for the 5-star-premium-gold users who do not forget this point!
👍 🏅 🏆
- The full error message that you are seeing (in particular file names and line numbers of the stack-trace).
- Which version of Julia and
NCDatasetsare you using? Please include the output of:
versioninfo() using Pkg Pkg.installed()["NCDatasets"]
NCDatasetspass its test suite? Please include the output of:
using Pkg Pkg.test("NCDatasets")
The package NetCDF.jl from Fabian Gans and contributors is an alternative to this package which supports a more Matlab/Octave-like interface for reading and writing NetCDF files.
build.jl and the error handling code of the NetCDF C API are from NetCDF.jl by Fabian Gans (Max-Planck-Institut für Biogeochemie, Jena, Germany) released under the MIT license.