A Clojure library which wraps the Java netcdf4 library from Unidata. See https://www.unidata.ucar.edu/software/netcdf-java/
This is a very basic wrapper around only part of the Java API based on what I
needed for my own NetCDF file processing. At this point, there is no support for
writing NetCDF files, only reading and extracting data from variables in these
files. The API is based around Clojure map
structures representing NetCDF
attributes, variables and arrays. Each map also contains an :obj
key, which
contains the corresponding raw Java object i.e. Attibute
, Variable
, Array
etc. This makes it easy to call any of the many other methods provided by the
various Java classes which do not have a basic Clojure based function wrapper.
In addition to the :obj
key, each map also contains keys representing various
static data associated with each object e.g. attribute name, variable name or
type, array rank, size and shape etc. See the documentation for each map
for
details.
The most frequently used functions in this library are all aliased in the
theophilusx.netcdf.core
namespace. In most cases, just loading this namespace
will provide all the functionality you need.
Most of the interface is based on Clojure maps. Each key NetCDF data structure
is represented as a Clojure map (variables, dimensions, attributes, etc). Each
map has keys representing key information about the underlying object e.g.
:name
, :type
, :size
etc. In addition, each map also contains an :obj
key
which contains the raw underlying Java object. This allows easy access to
additional Java library operations based on Clojure’s Java interop facilities.
Codox generated documentation can be found at https://theophilusx.github.io/netcdf
The following name spaces are implemented by the library.
Name Space | Description |
---|---|
theophilusx.netcdf.arrays | Processing of array data |
theophilusx.netcdf.attributes | Access NetCDF attribute data |
theophilusx.netcdf.core | Convenience name space which contains aliases |
to public functions in other name spaces | |
theophilusx.netcdf.data | Basic functions to read data from a NeteCDF variable |
theophilusx.netcdf.dimensions | Access to variable dimension information |
theophilusx.netcdf.file | Functions to open/read NetCDF files |
theophilusx.netcdf.groups | Access data on NetCDF groups |
theophilusx.netcdf.ranges | Generate and manipulate Range objects |
theophilusx.netcdf.variables | Access and process NetCDF variables |
The theophilusx.netecdf.file
namespace contains various functions used to open
a NetCDF file and retrieve some metadata about the file. The two main functions
for opening a NetCDF file are open
and open-in-memory
. There is also a
close
function to close the file. The opening functions return a NetcdfFile
Java object. Often, you won’t use these functions directly, but instead use the
macros with-netcdf
and with-memory-netcdf
instead. These macros allow you to
open a NetCDF file, perform some operations and then automatically close and
free the resource once done.
(ns demo.core
(:require [theophilusx.netcdf.core :as core]))
(core/with-netcdf [nc "./data.nc"]
(let [vs (core/variables nc)]
(for [v vs]
(println (str "Name: " (:name v)
" Description: " (:description v))))))
The read-value
function provides a way to read a single value from a NetCDF
variable. For example
(ns demo.core
(:require [theophilusx.netcdf.core :as core]))
(core/with-netcdf [nc "./data.nc"]
(let [v (core/variable nc "tasmax")
val (core/read-value v [1 300 400])]
(println (str "The value at index 1 300 400 is " val
" for variable tasmax"))))
In the above example, the variable tasmax
is a 3 dimensional array. The
example returns the value at indice [1 300 400]
. While this is fine for
reading a single value, it is an inefficient method for reading multiple values.
For this, you would use the read-slice
function. for example
(ns demo.core
(:require [theophilusx.netcdf.core :as core]))
(core/with-netcdf [nc "./data.nc"]
(let [v (core/variable nc "tasmax")
ar (core/read-slice v [0 300 400] [2 2 2])]
(for [j [0 1]
k [0 1]
l [0 1]]
(println (str "Value at [" j " " k " " l "] is "
(core/get-value ar j k l))))))
The read-slice
function returns a multi-dimensional array of the values from
the tasmax
variable. The array specifies the origin
i.e. starting index for
each dimension and the shape
i.e. number of elements from each dimension. In
the above example, the array is 3 dimensional with 2 elements in each dimension
with each dimension starting at [0 300 400]
respectively.
Copyright © 2019 Tim Cross
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.