CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-h5netcdf

netCDF4 file access via h5py with hierarchical and legacy APIs for scientific computing

69

0.83x
Overview
Eval results
Files

dimensions.mddocs/

Dimensions Management

Dimensions define the coordinate system and shape constraints for variables in netCDF4 files. They can be fixed-size or unlimited, and serve as the foundation for all variable definitions and data organization.

Capabilities

Dimension Creation and Access

Create and manage dimensions within groups.

class Dimensions(MutableMapping):
    def __getitem__(self, name: str) -> Dimension:
        """Get dimension by name."""
        ...
    
    def __setitem__(self, name: str, size: int) -> None:
        """Create new dimension with specified size."""
        ...
    
    def __delitem__(self, name: str) -> None:
        """Remove dimension (if not used by variables)."""
        ...
    
    def __contains__(self, name: str) -> bool:
        """Check if dimension exists."""
        ...
    
    def __iter__(self):
        """Iterate over dimension names."""
        ...
    
    def __len__(self) -> int:
        """Number of dimensions in this group."""
        ...

Dimension Objects

Individual dimension properties and methods.

class Dimension:
    def __init__(self, parent: Group, name: str, size: int = None, 
                 create_h5ds: bool = False, phony: bool = False):
        """
        Create or access a dimension.
        
        Args:
            parent (Group): Parent group containing this dimension
            name (str): Dimension name
            size (int): Dimension size (None for unlimited)
            create_h5ds (bool): Create HDF5 dimension scale
            phony (bool): Whether this is a phony dimension
        """
        ...
    
    @property
    def name(self) -> str:
        """Dimension name."""
        ...
    
    @property
    def size(self) -> int:
        """Current dimension size."""
        ...
    
    def isunlimited(self) -> bool:
        """Check if dimension is unlimited."""
        ...
    
    def group(self) -> Group:
        """Return parent group."""
        ...

Dimension Management Operations

Advanced dimension operations and utilities.

def add(self, name: str) -> None:
    """Add existing dimension from parent groups."""
    ...

def add_phony(self, name: str, size: int) -> None:
    """Add phony dimension for unlabeled axes."""
    ...

def resize_dimension(self, dim: str, size: int) -> None:
    """Resize unlimited dimension."""
    ...

Usage Examples

Basic Dimension Operations

import h5netcdf

with h5netcdf.File('dimensions.nc', 'w') as f:
    # Create fixed-size dimensions
    f.dimensions['lat'] = 180
    f.dimensions['lon'] = 360
    f.dimensions['level'] = 50
    
    # Create unlimited dimension
    f.dimensions['time'] = None  # None indicates unlimited
    
    # Access dimension properties
    lat_dim = f.dimensions['lat']
    print(f"Latitude dimension size: {lat_dim.size}")
    print(f"Is unlimited: {lat_dim.isunlimited()}")
    
    # Check if dimension exists
    if 'time' in f.dimensions:
        time_dim = f.dimensions['time']
        print(f"Time is unlimited: {time_dim.isunlimited()}")
    
    # List all dimensions
    print(f"Dimensions: {list(f.dimensions.keys())}")
    print(f"Number of dimensions: {len(f.dimensions)}")

Unlimited Dimensions

with h5netcdf.File('unlimited.nc', 'w') as f:
    # Create unlimited dimension
    f.dimensions['time'] = None
    f.dimensions['station'] = 100
    
    # Create variable using unlimited dimension
    temp = f.create_variable('temperature', ('time', 'station'), dtype='f4')
    
    # Initially, unlimited dimension has size 0
    print(f"Initial time size: {f.dimensions['time'].size}")
    
    # Writing data extends the unlimited dimension
    temp[0, :] = np.random.random(100)
    print(f"After first write: {f.dimensions['time'].size}")
    
    temp[1, :] = np.random.random(100)
    print(f"After second write: {f.dimensions['time'].size}")
    
    # Can explicitly resize unlimited dimensions
    f.resize_dimension('time', 10)
    print(f"After resize: {f.dimensions['time'].size}")

Coordinate Variables and Dimensions

with h5netcdf.File('coordinates.nc', 'w') as f:
    # Create dimensions
    f.dimensions['x'] = 100
    f.dimensions['y'] = 50
    f.dimensions['time'] = None
    
    # Create coordinate variables (same name as dimension)
    x_coord = f.create_variable('x', ('x',), dtype='f4')
    x_coord[:] = np.linspace(0, 99, 100)
    x_coord.attrs['units'] = 'm'
    x_coord.attrs['long_name'] = 'X coordinate'
    
    y_coord = f.create_variable('y', ('y',), dtype='f4')
    y_coord[:] = np.linspace(0, 49, 50)
    y_coord.attrs['units'] = 'm'
    y_coord.attrs['long_name'] = 'Y coordinate'
    
    # Time coordinate (unlimited)
    time_coord = f.create_variable('time', ('time',), dtype='f8')
    time_coord.attrs['units'] = 'days since 2023-01-01'
    time_coord.attrs['calendar'] = 'standard'
    
    # Data variable using these dimensions
    data = f.create_variable('temperature', ('time', 'y', 'x'), dtype='f4')
    
    # Write time series data
    for t in range(5):
        time_coord[t] = t
        data[t, :, :] = np.random.random((50, 100)) * 30 + 273.15

Dimension Inheritance in Groups

with h5netcdf.File('groups_dims.nc', 'w') as f:
    # Create dimensions in root group
    f.dimensions['time'] = None
    f.dimensions['lat'] = 180
    f.dimensions['lon'] = 360
    
    # Create child group
    surface = f.create_group('surface')
    
    # Child group can use parent dimensions
    surface.dimensions.add('time')  # Reference parent's time dimension
    surface.dimensions.add('lat')   # Reference parent's lat dimension
    surface.dimensions.add('lon')   # Reference parent's lon dimension
    
    # Or create group-specific dimensions
    surface.dimensions['height'] = 10
    
    # Create variable using mixed dimensions
    temp = surface.create_variable(
        'temperature', 
        ('time', 'height', 'lat', 'lon'), 
        dtype='f4'
    )
    
    print(f"Root dimensions: {list(f.dimensions.keys())}")
    print(f"Surface dimensions: {list(surface.dimensions.keys())}")

Checking Dimension Usage

with h5netcdf.File('check_usage.nc', 'r') as f:
    for dim_name, dimension in f.dimensions.items():
        print(f"Dimension: {dim_name}")
        print(f"  Size: {dimension.size}")
        print(f"  Unlimited: {dimension.isunlimited()}")
        
        # Find variables using this dimension
        using_vars = []
        for var_name, variable in f.variables.items():
            if dim_name in variable.dimensions:
                using_vars.append(var_name)
        
        print(f"  Used by variables: {using_vars}")
        
        # Check if coordinate variable exists
        if dim_name in f.variables:
            coord_var = f.variables[dim_name]
            print(f"  Has coordinate variable: {coord_var.dtype}")
        else:
            print(f"  No coordinate variable")

Phony Dimensions

# Phony dimensions handle unlabeled axes in HDF5 files
with h5netcdf.File('unlabeled.nc', 'r', phony_dims='sort') as f:
    # If file has unlabeled dimensions, they get phony names
    for dim_name, dimension in f.dimensions.items():
        if hasattr(dimension, 'phony') and dimension.phony:
            print(f"Phony dimension: {dim_name} (size: {dimension.size})")

Dimension Validation

with h5netcdf.File('validate.nc', 'w') as f:
    try:
        # This will work
        f.dimensions['valid_name'] = 100
        
        # This might cause issues depending on backend
        # f.dimensions[''] = 50  # Empty name
        
        # Creating variable with non-existent dimension will fail
        # f.create_variable('test', ('nonexistent',), dtype='f4')
        
    except Exception as e:
        print(f"Validation error: {e}")

Multiple Unlimited Dimensions

# Note: NetCDF4 format supports multiple unlimited dimensions
with h5netcdf.File('multi_unlimited.nc', 'w') as f:
    # Multiple unlimited dimensions (netCDF4 feature)
    f.dimensions['time'] = None
    f.dimensions['ensemble'] = None
    f.dimensions['lat'] = 90
    f.dimensions['lon'] = 180
    
    # Variable with multiple unlimited dimensions
    temp = f.create_variable(
        'temperature', 
        ('time', 'ensemble', 'lat', 'lon'), 
        dtype='f4'
    )
    
    # Write data to extend both unlimited dimensions
    temp[0, 0, :, :] = np.random.random((90, 180))
    temp[1, 2, :, :] = np.random.random((90, 180))
    
    print(f"Time size: {f.dimensions['time'].size}")
    print(f"Ensemble size: {f.dimensions['ensemble'].size}")

Dimension Naming Conventions

Standard Names

  • time: Temporal coordinate
  • lat, latitude: Latitude coordinate
  • lon, longitude: Longitude coordinate
  • level, lev: Vertical levels
  • height, depth: Vertical distance coordinates

Best Practices

  • Use descriptive names that indicate the coordinate type
  • Avoid spaces and special characters
  • Be consistent within and across files
  • Consider CF (Climate and Forecast) conventions for geophysical data

Dimension Constraints

  • Dimension names must be unique within a group
  • Cannot delete dimensions that are used by variables
  • Unlimited dimensions can only grow, not shrink (use resize_dimension)
  • Fixed dimensions cannot be resized after creation
  • Each variable can reference dimensions from its group or parent groups

Install with Tessl CLI

npx tessl i tessl/pypi-h5netcdf

docs

attributes.md

dimensions.md

file-operations.md

groups.md

index.md

legacy-api.md

user-types.md

variables.md

tile.json