Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions pyfive/high_level.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
""" High-level classes for reading HDF5 files. """

from collections import Mapping, deque
from collections import Mapping, deque, Sequence
from io import open # Python 2.7 requires for a Buffered Reader

import numpy as np
Expand Down Expand Up @@ -299,11 +299,47 @@ def fillvalue(self):
@property
def dims(self):
""" dims attribute. """
raise NotImplementedError
return DimensionManager(self)

@property
def attrs(self):
""" attrs attribute. """
if self._attrs is None:
self._attrs = self._dataobjects.get_attributes()
return self._attrs


class DimensionManager(Sequence):
""" Represents a collection of dimensions associated with a dataset. """
def __init__(self, dset):
ndim = len(dset.shape)
dim_list = [[]]*ndim
if 'DIMENSION_LIST' in dset.attrs:
dim_list = dset.attrs['DIMENSION_LIST']
dim_labels = [b'']*ndim
if 'DIMENSION_LABELS' in dset.attrs:
dim_labels = dset.attrs['DIMENSION_LABELS']
self._dims = [
DimensionProxy(dset.file, label, refs) for
label, refs in zip(dim_labels, dim_list)]

def __len__(self):
return len(self._dims)

def __getitem__(self, x):
return self._dims[x]


class DimensionProxy(Sequence):
""" Represents a HDF5 "dimension". """

def __init__(self, dset_file, label, refs):
self.label = label.decode('utf-8')
self._refs = refs
self._file = dset_file

def __len__(self):
return len(self._refs)

def __getitem__(self, x):
return self._file[self._refs[x]]
Binary file added tests/dim_scales.hdf5
Binary file not shown.
39 changes: 39 additions & 0 deletions tests/make_dim_scales.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#! /usr/bin/env python
""" Create a HDF5 file with dimension scales and labels . """
import h5py
import numpy as np

f = h5py.File('dim_scales.hdf5', 'w')

common_args = {
'track_times': False,
'dtype': 'i4',
}

# dataset with dimension labels and scales
f.create_dataset('dset1', data=np.ones((4, 3, 2)), **common_args)

# dimension labels
f['dset1'].dims[0].label = 'z'
f['dset1'].dims[1].label = 'y'
f['dset1'].dims[2].label = 'x'

# dimension scales
f.create_dataset('x1', data=[1, 2], **common_args)
f.create_dataset('y1', data=[3, 4, 5], **common_args)
f.create_dataset('z1', data=[0, 10, 20, 30], **common_args)
f.create_dataset('x2', data=[99, 98], **common_args)

f['dset1'].dims.create_scale(f['x1'], 'x1_name')
f['dset1'].dims.create_scale(f['y1'], 'y1_name')
f['dset1'].dims.create_scale(f['z1'], 'z1_name')

f['dset1'].dims[0].attach_scale(f['z1'])
f['dset1'].dims[1].attach_scale(f['y1'])
f['dset1'].dims[2].attach_scale(f['x1'])
f['dset1'].dims[2].attach_scale(f['x2'])

# dataset with no dimension entries
f.create_dataset('dset2', data=np.ones((4, 3, 2)), **common_args)

f.close()
64 changes: 64 additions & 0 deletions tests/test_dim_scales.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
""" Unit tests for pyfive dimension scales. """

import os

from numpy.testing import assert_array_equal

import pyfive

DIRNAME = os.path.dirname(__file__)
DIM_SCALES_HDF5_FILE = os.path.join(DIRNAME, './dim_scales.hdf5')


def test_dim_labels():

hfile = pyfive.File(DIM_SCALES_HDF5_FILE)

# dataset with dimension labels
dims = hfile['dset1'].dims
assert dims[0].label == 'z'
assert dims[1].label == 'y'
assert dims[2].label == 'x'

# dataset with no dimension labels
dims = hfile['dset2'].dims
assert dims[0].label == ''
assert dims[1].label == ''
assert dims[2].label == ''

hfile.close()


def test_dim_scales():

hfile = pyfive.File(DIM_SCALES_HDF5_FILE)

# dataset with dimension scales
dims = hfile['dset1'].dims

assert len(dims) == 3

assert len(dims[0]) == 1
assert len(dims[1]) == 1
assert len(dims[2]) == 2

assert dims[0][0].name == '/z1'
assert dims[1][0].name == '/y1'
assert dims[2][0].name == '/x1'
assert dims[2][1].name == '/x2'

assert_array_equal(dims[0][0][:], [0, 10, 20, 30])
assert_array_equal(dims[1][0][:], [3, 4, 5])
assert_array_equal(dims[2][0][:], [1, 2])
assert_array_equal(dims[2][1][:], [99, 98])

# dataset with no dimension scales
dims = hfile['dset2'].dims

assert len(dims) == 3

assert len(dims[0]) == 0
assert len(dims[1]) == 0
assert len(dims[2]) == 0

hfile.close()