Skip to content

Commit

Permalink
netcdf: add convenience methods for indexing a NetCDF file
Browse files Browse the repository at this point in the history
  • Loading branch information
gauteh committed Sep 7, 2023
1 parent d3a6d51 commit 64aafb2
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 2 deletions.
68 changes: 68 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ rayon = "1.6"
ndarray = { version = "0.15", features = [ "rayon" ] }
pyo3 = { version = "0.17.3", optional = true, features = ["anyhow", "auto-initialize", "abi3-py38"] }
numpy = { version = "0.17.2", optional = true }
netcdf = { version = "^0.8", optional = true }

[dependencies.serde]
features = ["derive"]
Expand All @@ -64,9 +65,10 @@ codegen-units = 1
debug = true

[features]
default = ["static", "fast-index"]
static = ["hdf5-sys/static", "hdf5-sys/zlib"]
default = ["static", "fast-index", "netcdf"]
static = ["hdf5-sys/static", "hdf5-sys/zlib", "netcdf?/static"]
fast-index = []
python = ["pyo3", "numpy"]
extension-module = ["python", "pyo3/extension-module"]
netcdf = [ "dep:netcdf" ]

26 changes: 26 additions & 0 deletions src/idx/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ impl TryFrom<&hdf5::File> for Index<'_> {
}
}

#[cfg(feature = "netcdf")]
impl TryFrom<&netcdf::File> for Index<'_> {
type Error = anyhow::Error;

fn try_from(f: &netcdf::File) -> Result<Index<'static>, anyhow::Error> {
let path = PathBuf::from(&f.path()?);

Index::index(path)
}
}

impl Index<'_> {
/// Open an existing HDF5 file and index all variables.
#[allow(clippy::self_named_constructors)]
Expand Down Expand Up @@ -137,6 +148,21 @@ mod tests {
r.values::<f32>(None, None).unwrap();
}

#[test]
#[cfg(feature = "netcdf")]
fn index_from_netcdf() {
use std::convert::TryInto;

let f = netcdf::open("tests/data/coads_climatology.nc4").unwrap();
let i: Index = (&f).try_into().unwrap();
let mut r = i.reader("SST").unwrap();
let iv = r.values::<f32>(None, None).unwrap();

let nv = f.variable("SST").unwrap().values::<f32, _>(..).unwrap();

assert_eq!(iv, nv);
}

#[test]
fn index_from_path() {
use std::convert::TryInto;
Expand Down
17 changes: 17 additions & 0 deletions src/idx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ impl IntoIndex for hdf5::Dataset {
}
}

#[cfg(feature = "netcdf")]
impl IntoIndex for netcdf::File {
type Indexed = Index<'static>;

fn index(&self) -> anyhow::Result<Self::Indexed> {
self.try_into()
}
}

#[cfg(test)]
mod test {
use super::*;
Expand All @@ -55,6 +64,14 @@ mod test {
println!("index: {:#?}", i);
}

#[test]
#[cfg(feature = "netcdf")]
fn into_idx_netcdf() {
let hf = netcdf::open("tests/data/coads_climatology.nc4").unwrap();
let i = hf.index().unwrap();
println!("index: {:#?}", i);
}

#[test]
fn into_idx_dataset() {
let hf = hdf5::File::open("tests/data/coads_climatology.nc4").unwrap();
Expand Down
36 changes: 36 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,42 @@
//! or convert a [hdf5::File] or [hdf5::Dataset] into an index by using
//! [`try_from`](std::convert::TryFrom) or the [`index`](idx::IntoIndex) method.
//!
//! or use the [IntoIndex](idx::IntoIndex) trait:
//!
//! ```
//! use hidefix::prelude::*;
//!
//! let i = hdf5::File::open("tests/data/coads_climatology.nc4").unwrap().index().unwrap();
//! let iv = i.reader("SST").unwrap().values::<f32>(None, None).unwrap();
//! ```
//!
//! ## NetCDF4 files
//!
//! NetCDF4 uses HDF5 as their underlying data-format. Hidefix can be used to read the NetCDF
//! variables, though there might be extra decoding necessary. The hidefix-`xarray` does that for
//! you in the python bindings.
//!
//! ```
//! use std::convert::TryInto;
//! use hidefix::prelude::*;
//!
//! let f = netcdf::open("tests/data/coads_climatology.nc4").unwrap();
//! let nv = f.variable("SST").unwrap().values::<f32, _>(..).unwrap();
//!
//! let i: Index = (&f).try_into().unwrap();
//! let iv = i.reader("SST").unwrap().values::<f32>(None, None).unwrap();
//!
//! assert_eq!(iv, nv);
//! ```
//!
//! or use the [IntoIndex](idx::IntoIndex) trait:
//!
//! ```
//! use hidefix::prelude::*;
//!
//! let i = netcdf::open("tests/data/coads_climatology.nc4").unwrap().index().unwrap();
//! let iv = i.reader("SST").unwrap().values::<f32>(None, None).unwrap();
//! ```
//!
//! It is also possible to [stream](reader::stream::StreamReader) the values. The streamer is
//! currently optimized for streaming bytes.
Expand Down

0 comments on commit 64aafb2

Please sign in to comment.