Skip to main content

Crate oxigdal_netcdf

Crate oxigdal_netcdf 

Source
Expand description

OxiGDAL NetCDF Driver - Pure Rust NetCDF-3 with Optional NetCDF-4 Support

This crate provides NetCDF file format support for OxiGDAL, following the COOLJAPAN Pure Rust policy.

§Pure Rust Policy Compliance

IMPORTANT: This driver provides the structure and API for Pure Rust NetCDF support, but the actual netcdf3 integration is currently incomplete due to breaking API changes in netcdf3 v0.6.0. The driver demonstrates:

  • Complete Pure Rust data structures for NetCDF metadata (dimensions, variables, attributes)
  • CF conventions support
  • Feature-gated architecture for Pure Rust vs. C-binding implementations

Status: The reader/writer implementations need to be updated to use the new Dataset/FileReader/FileWriter API from netcdf3 v0.6.0 (breaking change from v0.1.0).

For NetCDF-4 (HDF5-based) support, you can enable the netcdf4 feature, which requires system libraries (libnetcdf, libhdf5) and is NOT Pure Rust.

§Feature Flags

  • netcdf3 (default): Pure Rust NetCDF-3 support via netcdf3 crate
  • netcdf4: NetCDF-4/HDF5 support via C bindings (requires system libraries)
  • cf_conventions: CF (Climate and Forecast) conventions support
  • async: Async I/O support
  • compression: Compression support (NetCDF-4 only)

§NetCDF Format Support

§NetCDF-3 (Pure Rust, Default)

Fully supported data types:

  • i8, i16, i32 - Signed integers
  • f32, f64 - Floating point numbers
  • char - Character data

Features:

  • Fixed and unlimited dimensions
  • Multi-dimensional arrays
  • Variable and global attributes
  • Coordinate variables

§NetCDF-4 (C Bindings, Feature-Gated)

Additional data types (requires netcdf4 feature):

  • u8, u16, u32, u64 - Unsigned integers
  • i64, u64 - 64-bit integers
  • string - Variable-length strings

Additional features (requires netcdf4 feature):

  • HDF5-based compression
  • Groups and nested groups
  • User-defined types
  • Multiple unlimited dimensions

§Example - Reading NetCDF-3 File (Pure Rust)

use oxigdal_netcdf::NetCdfReader;

// Open a NetCDF-3 file
let reader = NetCdfReader::open("data.nc")?;

// Get metadata
println!("{}", reader.metadata().summary());

// List dimensions
for dim in reader.dimensions().iter() {
    println!("Dimension: {} (size: {})", dim.name(), dim.len());
}

// List variables
for var in reader.variables().iter() {
    println!("Variable: {} (type: {})", var.name(), var.data_type().name());
}

// Read variable data
let temperature = reader.read_f32("temperature")?;
println!("Temperature data: {:?}", temperature);

§Example - Writing NetCDF-3 File (Pure Rust)

use oxigdal_netcdf::{NetCdfWriter, NetCdfVersion};
use oxigdal_netcdf::dimension::Dimension;
use oxigdal_netcdf::variable::{Variable, DataType};
use oxigdal_netcdf::attribute::{Attribute, AttributeValue};

// Create a new NetCDF-3 file
let mut writer = NetCdfWriter::create("output.nc", NetCdfVersion::Classic)?;

// Add dimensions
writer.add_dimension(Dimension::new_unlimited("time", 0)?)?;
writer.add_dimension(Dimension::new("lat", 180)?)?;
writer.add_dimension(Dimension::new("lon", 360)?)?;

// Add coordinate variables
writer.add_variable(Variable::new_coordinate("time", DataType::F64)?)?;
writer.add_variable(Variable::new_coordinate("lat", DataType::F32)?)?;
writer.add_variable(Variable::new_coordinate("lon", DataType::F32)?)?;

// Add data variable
let temp_var = Variable::new(
    "temperature",
    DataType::F32,
    vec!["time".to_string(), "lat".to_string(), "lon".to_string()],
)?;
writer.add_variable(temp_var)?;

// Add variable attributes
writer.add_variable_attribute(
    "temperature",
    Attribute::new("units", AttributeValue::text("celsius"))?,
)?;
writer.add_variable_attribute(
    "temperature",
    Attribute::new("long_name", AttributeValue::text("Air Temperature"))?,
)?;

// Add global attributes
writer.add_global_attribute(
    Attribute::new("Conventions", AttributeValue::text("CF-1.8"))?,
)?;
writer.add_global_attribute(
    Attribute::new("title", AttributeValue::text("Temperature Data"))?,
)?;

// End define mode
writer.end_define_mode()?;

// Write data
let time_data = vec![0.0, 1.0, 2.0];
writer.write_f64("time", &time_data)?;

let lat_data: Vec<f32> = (0..180).map(|i| -90.0 + i as f32).collect();
writer.write_f32("lat", &lat_data)?;

let lon_data: Vec<f32> = (0..360).map(|i| -180.0 + i as f32).collect();
writer.write_f32("lon", &lon_data)?;

// Write temperature data
let temp_data = vec![20.0f32; 3 * 180 * 360];
writer.write_f32("temperature", &temp_data)?;

// Close file
writer.close()?;

§CF Conventions Support

The driver recognizes and parses CF (Climate and Forecast) conventions metadata:

use oxigdal_netcdf::NetCdfReader;

let reader = NetCdfReader::open("cf_data.nc")?;

if let Some(cf) = reader.cf_metadata() {
    if cf.is_cf_compliant() {
        println!("CF Conventions: {}", cf.conventions.as_deref().unwrap_or(""));
        println!("Title: {}", cf.title.as_deref().unwrap_or(""));
        println!("Institution: {}", cf.institution.as_deref().unwrap_or(""));
    }
}

§Pure Rust Limitations

When using the default Pure Rust mode (NetCDF-3 only):

  • No NetCDF-4/HDF5 format support
  • No compression support
  • No groups or user-defined types
  • Only one unlimited dimension allowed
  • Limited to NetCDF-3 data types

To use NetCDF-4 features, enable the netcdf4 feature (requires C dependencies):

[dependencies]
oxigdal-netcdf = { version = "0.1", features = ["netcdf4"] }

Note: Enabling netcdf4 violates the COOLJAPAN Pure Rust policy and requires system libraries (libnetcdf ≥ 4.0, libhdf5 ≥ 1.8).

§Performance Considerations

  • Pure Rust NetCDF-3 reader/writer has comparable performance to C libraries
  • For large datasets, consider using chunked reading/writing
  • Unlimited dimensions may have performance implications
  • CF metadata parsing is done on-demand

§References

Re-exports§

pub use attribute::Attribute;
pub use attribute::AttributeValue;
pub use attribute::Attributes;
pub use dimension::Dimension;
pub use dimension::DimensionSize;
pub use dimension::Dimensions;
pub use error::NetCdfError;
pub use error::Result;
pub use metadata::CfMetadata;
pub use metadata::NetCdfMetadata;
pub use metadata::NetCdfVersion;
pub use netcdf4::ChunkInfo;
pub use netcdf4::CompressionFilter;
pub use netcdf4::Hdf5ByteOrder;
pub use netcdf4::Hdf5DatatypeClass;
pub use netcdf4::Hdf5MessageType;
pub use netcdf4::Hdf5Superblock;
pub use netcdf4::Hdf5SuperblockVersion;
pub use netcdf4::Nc4Group;
pub use netcdf4::Nc4Reader;
pub use netcdf4::Nc4VariableInfo;
pub use netcdf4::Nc4Writer;
pub use reader::NetCdfReader;
pub use variable::DataType;
pub use variable::Variable;
pub use variable::Variables;
pub use writer::NetCdfWriter;

Modules§

attribute
NetCDF attribute types and utilities.
dimension
NetCDF dimension types and utilities.
error
Error types for NetCDF operations.
metadata
NetCDF file metadata structures.
netcdf4
Auto-generated module structure
reader
NetCDF file reader implementation.
variable
NetCDF variable types and utilities.
writer
NetCDF file writer implementation.

Constants§

NAME
Crate name
VERSION
Crate version

Functions§

has_netcdf3
Check if NetCDF-3 support is available.
has_netcdf4
Check if NetCDF-4 support is available.
info
Get driver information.
is_pure_rust
Pure Rust compliance status
supported_versions
Get supported format versions.