[h5py] 56/455: More h5t classes & improvements
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:17 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag 1.3.0
in repository h5py.
commit 4fede9aaef61a33ea5119d0a0bc36b371750a7f4
Author: andrewcollette <andrew.collette at gmail.com>
Date: Wed Jun 18 02:06:05 2008 +0000
More h5t classes & improvements
---
h5py/h5.pyx | 3 +
h5py/h5a.pyx | 4 +-
h5py/h5d.pxd | 2 +-
h5py/h5d.pyx | 2 +-
h5py/h5t.pxd | 19 ++++
h5py/h5t.pyx | 313 ++++++++++++++++++++++++++++++++++++-----------------------
6 files changed, 216 insertions(+), 127 deletions(-)
diff --git a/h5py/h5.pyx b/h5py/h5.pyx
index 11d7052..1d5cc14 100644
--- a/h5py/h5.pyx
+++ b/h5py/h5.pyx
@@ -81,6 +81,9 @@ cdef class ObjectID:
return "%d [%s] (%s) %s" % (self.id, ref, lstr, self.__class__.__name__)
+ def __repr__(self):
+ return self.__str__()
+
# === Automatic error handling ================================================
diff --git a/h5py/h5a.pyx b/h5py/h5a.pyx
index 45b585a..cf20d59 100644
--- a/h5py/h5a.pyx
+++ b/h5py/h5a.pyx
@@ -16,7 +16,7 @@
# Pyrex compile-time imports
from h5p cimport H5P_DEFAULT
-from h5t cimport TypeID
+from h5t cimport TypeID, typewrap
from h5s cimport SpaceID, H5Sclose
from numpy cimport import_array, ndarray, PyArray_DATA
@@ -262,7 +262,7 @@ cdef class AttrID(ObjectID):
Create and return a copy of the attribute's datatype.
"""
- return TypeID(H5Aget_type(self.id))
+ return typewrap(H5Aget_type(self.id))
diff --git a/h5py/h5d.pxd b/h5py/h5d.pxd
index ab28358..42fd690 100644
--- a/h5py/h5d.pxd
+++ b/h5py/h5d.pxd
@@ -20,7 +20,7 @@ from h5 cimport class ObjectID
cdef class DatasetID(ObjectID):
pass
-from h5t cimport class TypeID
+from h5t cimport class TypeID, typewrap
from h5s cimport class SpaceID
from h5p cimport class PropID, PropDCID, PropDXID, pdefault
from numpy cimport class ndarray
diff --git a/h5py/h5d.pyx b/h5py/h5d.pyx
index c5d4edf..648e429 100644
--- a/h5py/h5d.pyx
+++ b/h5py/h5d.pyx
@@ -232,7 +232,7 @@ cdef class DatasetID(ObjectID):
Create and return a new copy of the datatype for this dataset.
"""
- return TypeID(H5Dget_type(self.id))
+ return typewrap(H5Dget_type(self.id))
def get_create_plist(self):
""" () => PropDSCreateID
diff --git a/h5py/h5t.pxd b/h5py/h5t.pxd
index 7cf5ff7..9ac6adb 100644
--- a/h5py/h5t.pxd
+++ b/h5py/h5t.pxd
@@ -20,7 +20,26 @@ from h5 cimport class ObjectID
cdef class TypeID(ObjectID):
cdef object _complex_names
+cdef class TypeAtomicID(TypeID):
+ pass
+
+cdef class TypeCompositeID(TypeID):
+ pass
+
+cdef class TypeEnumID(TypeCompositeID):
+
cdef int enum_convert(self, long long *buf, int reverse) except -1
+
+cdef class TypeCompoundID(TypeCompositeID):
+ pass
+
+cdef class TypeArrayID(TypeID):
+ pass
+
+cdef class TypeOpaqueID(TypeID):
+ pass
+
+cdef object typewrap(hid_t id_)
cdef extern from "hdf5.h":
diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx
index 2126c26..a2a89ed 100644
--- a/h5py/h5t.pyx
+++ b/h5py/h5t.pyx
@@ -78,14 +78,6 @@ import h5
from h5 import DDict, ArgsError
import sys
-# === Custom C API ============================================================
-
-cdef object lockid(hid_t id_in):
- cdef TypeID tid
- tid = TypeID(id_in)
- tid._locked = 1
- return tid
-
# === Public constants and data structures ====================================
# Enumeration H5T_class_t
@@ -187,6 +179,42 @@ _complex_map = { "<c8": IEEE_F32LE, "<c16": IEEE_F64LE,
_order_map = { H5T_ORDER_NONE: '|', H5T_ORDER_LE: '<', H5T_ORDER_BE: '>'}
_sign_map = { H5T_SGN_NONE: 'u', H5T_SGN_2: 'i' }
+_class_names = { H5T_INTEGER: "INTEGER",
+ H5T_FLOAT: "FLOAT",
+ H5T_TIME: "TIME",
+ H5T_STRING: "STRING",
+ H5T_BITFIELD: "BITFIELD",
+ H5T_OPAQUE: "OPAQUE",
+ H5T_COMPOUND: "COMPOUND",
+ H5T_REFERENCE: "REFERENCE",
+ H5T_ENUM: "ENUM",
+ H5T_VLEN: "VLEN",
+ H5T_ARRAY: "ARRAY" }
+
+# === Custom C API ============================================================
+
+cdef object typewrap(hid_t id_):
+ _classes = { H5T_INTEGER: TypeAtomicID,
+ H5T_FLOAT: TypeAtomicID,
+ H5T_TIME: TypeID,
+ H5T_STRING: TypeAtomicID,
+ H5T_BITFIELD: TypeAtomicID,
+ H5T_OPAQUE: TypeOpaqueID,
+ H5T_COMPOUND: TypeCompoundID,
+ H5T_REFERENCE: TypeID,
+ H5T_ENUM: TypeEnumID,
+ H5T_VLEN: TypeAtomicID,
+ H5T_ARRAY: TypeArrayID }
+ cdef H5T_class_t cls
+ cls = H5Tget_class(id_)
+ return _classes.get(cls, TypeID)(id_)
+
+cdef object lockid(hid_t id_in):
+ cdef TypeID tid
+ tid = typewrap(id_in)
+ tid._locked = 1
+ return tid
+
# === General datatype operations =============================================
def create(int classtype, size_t size):
@@ -199,14 +227,14 @@ def create(int classtype, size_t size):
if classtype != H5T_COMPOUND and classtype != H5T_OPAQUE and \
classtype != H5T_ENUM:
raise ValueError("Class must be COMPOUND, OPAQUE or ENUM")
- return TypeID(H5Tcreate(<H5T_class_t>classtype, size))
+ return typewrap(H5Tcreate(<H5T_class_t>classtype, size))
def open(ObjectID group not None, char* name):
""" (ObjectID group, STRING name) => TypeID
Open a named datatype from a file.
"""
- return TypeID(H5Topen(group.id, name))
+ return typewrap(H5Topen(group.id, name))
def array_create(TypeID base not None, object dims_tpl):
""" (TypeID base, TUPLE dimensions)
@@ -230,18 +258,18 @@ def array_create(TypeID base not None, object dims_tpl):
efree(dims)
def enum_create(TypeID base not None):
- """ (TypeID base) => TypeID new_enum
+ """ (TypeID base) => TypeID
Create a new enumerated type based on an (integer) parent type.
"""
- return TypeID(H5Tenum_create(base.id))
+ return typewrap(H5Tenum_create(base.id))
-# === XXXX ====
cdef class TypeID(ObjectID):
"""
- Represents an HDF5 datatype identifier.
+ Represents an HDF5 datatype identifier, and encapsulates common
+ operations.
Python properties:
dtype: Numpy representation of the datatype.
@@ -264,6 +292,10 @@ cdef class TypeID(ObjectID):
self._complex_names = item
+ property dtype:
+ def __get__(self):
+ return self.py_dtype()
+
def commit(self, ObjectID group not None, char* name):
""" (ObjectID group, STRING name)
@@ -283,7 +315,7 @@ cdef class TypeID(ObjectID):
Create a copy of this type object.
"""
- return TypeID(H5Tcopy(self.id))
+ return typewrap(H5Tcopy(self.id))
def equal(self, TypeID typeid):
""" (TypeID typeid) => BOOL
@@ -309,6 +341,13 @@ cdef class TypeID(ObjectID):
"""
return <int>H5Tget_class(self.id)
+ def set_size(self, size_t size):
+ """ (UINT size)
+
+ Set the total size of the datatype, in bytes.
+ """
+ H5Tset_size(self.id, size)
+
def get_size(self):
""" () => INT size
@@ -321,7 +360,7 @@ cdef class TypeID(ObjectID):
Determine the parent type of an array or enumeration datatype.
"""
- return TypeID(H5Tget_super(self.id))
+ return typewrap(H5Tget_super(self.id))
def get_native_type(self, int direction=H5T_DIR_DEFAULT):
""" (INT direction=DIR_DEFAULT) => TypeID
@@ -336,7 +375,7 @@ cdef class TypeID(ObjectID):
The returned datatype is always an unlocked copy of one of NATIVE_*
"""
- return TypeID(H5Tget_native_type(self.id, <H5T_direction_t>direction))
+ return typewrap(H5Tget_native_type(self.id, <H5T_direction_t>direction))
def detect_class(self, int classtype):
""" (INT classtype) => BOOL class_is_present
@@ -352,14 +391,98 @@ cdef class TypeID(ObjectID):
if not self._locked:
H5Tclose(self.id)
- # === Atomic datatype operations ==========================================
-
- def set_size(self, size_t size):
- """ (UINT size)
+ def py_dtype(self):
+ """ ()
- Set the total size of the datatype, in bytes.
+ Create a Numpy dtype object as similar as possible to the given
+ HDF5 datatype object. The result is guaranteed to be logically
+ compatible with the original object, with no loss of precision,
+ but may not implement the same memory layout as the HDF5 type.
"""
- H5Tset_size(self.id, size)
+ cdef TypeID tmp_type
+ cdef H5T_class_t classtype
+ classtype = self.get_class()
+
+ if classtype == H5T_INTEGER:
+ typeobj = dtype( _order_map[self.get_order()] +
+ _sign_map[self.get_sign()] + str(self.get_size()) )
+
+ elif classtype == H5T_FLOAT:
+ typeobj = dtype( _order_map[self.get_order()] +
+ "f" + str(self.get_size()) )
+
+ elif classtype == H5T_STRING:
+ if self.is_variable_str():
+ raise ValueError("Variable-length strings are not supported.")
+
+ typeobj = dtype("|S" + str(self.get_size()))
+
+ elif classtype == H5T_OPAQUE:
+ typeobj = dtype("|V" + str(self.get_size()))
+
+ elif classtype == H5T_COMPOUND:
+
+ nfields = self.get_nmembers()
+ field_names = []
+ field_types = []
+
+ # First step: read field names and their Numpy dtypes into
+ # two separate arrays.
+ for i from 0 <= i < nfields:
+ tmp_type = self.get_member_type(i)
+ tmp_type.complex_names = self.complex_names
+ try:
+ field_names.append(self.get_member_name(i))
+ field_types.append(tmp_type.py_dtype())
+ finally:
+ tmp_type.close()
+
+ # 1. Check if it should be converted to a complex number
+ if len(field_names) == 2 and \
+ tuple(field_names) == self.complex_names and \
+ field_types[0] == field_types[1] and \
+ field_types[0].kind == 'f':
+
+ bstring = field_types[0].str
+ blen = int(bstring[2:])
+ nstring = bstring[0] + "c" + str(2*blen)
+ typeobj = dtype(nstring)
+
+ # 2. Otherwise, read all fields of the compound type, in HDF5 order.
+ else:
+ typeobj = dtype(zip(field_names, field_types))
+
+ elif classtype == H5T_ENUM:
+ # Have to recover enum dictionaries manually.
+ tmp_type = self.get_super()
+ try:
+ typeobj = tmp_type.py_dtype()
+ finally:
+ tmp_type.close()
+
+ elif classtype == H5T_ARRAY:
+ tmp_type = self.get_super()
+ tmp_type.complex_names = self.complex_names
+ try:
+ base_dtype = tmp_type.py_dtype()
+ finally:
+ tmp_type.close()
+ shape = tid.get_array_dims()
+ typeobj = dtype( (base_dtype, shape) )
+
+ else:
+ raise ValueError('Unsupported datatype class "%s"' % PY_NAMES[classtype])
+
+ return typeobj
+
+ def __str__(self):
+ return ObjectID.__str__(self)+": "+_class_names.get(self.get_class(), "UNKNOWN")
+
+cdef class TypeAtomicID(TypeID):
+
+ """
+ Represents an atomic datatype (including variable-length datatypes).
+ """
def get_order(self):
""" () => INT order
@@ -408,7 +531,12 @@ cdef class TypeID(ObjectID):
"""
return pybool(H5Tis_variable_str(self.id))
- # === Compound datatype operations ========================================
+
+cdef class TypeCompositeID(TypeID):
+
+ """
+ Encapsulates operations common to both enumerated and compound types.
+ """
def get_nmembers(self):
""" () => INT number_of_members
@@ -417,16 +545,6 @@ cdef class TypeID(ObjectID):
"""
return H5Tget_nmembers(self.id)
- def get_member_class(self, int member):
- """ (INT member) => INT class
-
- Determine the datatype class of the member of a compound type,
- identified by its index (0 <= member < nmembers).
- """
- if member < 0:
- raise ValueError("Member index must be non-negative.")
- return H5Tget_member_class(self.id, member)
-
def get_member_name(self, int member):
""" (INT member) => STRING name
@@ -456,6 +574,25 @@ cdef class TypeID(ObjectID):
"""
return H5Tget_member_index(self.id, name)
+
+cdef class TypeCompoundID(TypeCompositeID):
+
+ """
+ Represents a compound datatype
+ """
+
+
+ def get_member_class(self, int member):
+ """ (INT member) => INT class
+
+ Determine the datatype class of the member of a compound type,
+ identified by its index (0 <= member < nmembers).
+ """
+ if member < 0:
+ raise ValueError("Member index must be non-negative.")
+ return H5Tget_member_class(self.id, member)
+
+
def get_member_offset(self, int member):
""" (INT member) => INT offset
@@ -472,7 +609,7 @@ cdef class TypeID(ObjectID):
"""
if member < 0:
raise ValueError("Member index must be non-negative.")
- return TypeID(H5Tget_member_type(self.id, member))
+ return typewrap(H5Tget_member_type(self.id, member))
def insert(self, char* name, size_t offset, TypeID field not None):
""" (STRING name, UINT offset, TypeID field)
@@ -491,7 +628,11 @@ cdef class TypeID(ObjectID):
"""
H5Tpack(self.id)
- # === Array datatype operations ===========================================
+cdef class TypeArrayID(TypeID):
+
+ """
+ Represents an array datatype
+ """
def get_array_ndims(self):
""" () => INT rank
@@ -518,7 +659,11 @@ cdef class TypeID(ObjectID):
finally:
efree(dims)
- # === Enumeration datatypes ===============================================
+cdef class TypeEnumID(TypeCompositeID):
+
+ """
+ Represents an enumerated type
+ """
cdef int enum_convert(self, long long *buf, int reverse) except -1:
# Convert the long long value in "buf" to the native representation
@@ -603,7 +748,11 @@ cdef class TypeID(ObjectID):
self.enum_convert(&val, 1)
return val
- # === Opaque datatypes ====================================================
+cdef class TypeOpaqueID(TypeID):
+
+ """
+ Represents an opaque type
+ """
def set_tag(self, char* tag):
""" (STRING tag)
@@ -628,89 +777,7 @@ cdef class TypeID(ObjectID):
finally:
free(buf)
- def py_dtype(self):
- """ ()
-
- Create a Numpy dtype object as similar as possible to the given
- HDF5 datatype object. The result is guaranteed to be logically
- compatible with the original object, with no loss of precision,
- but may not implement the same memory layout as the HDF5 type.
- """
- cdef TypeID tmp_type
- cdef H5T_class_t classtype
- classtype = self.get_class()
-
- if classtype == H5T_INTEGER:
- typeobj = dtype( _order_map[self.get_order()] +
- _sign_map[self.get_sign()] + str(self.get_size()) )
-
- elif classtype == H5T_FLOAT:
- typeobj = dtype( _order_map[self.get_order()] +
- "f" + str(self.get_size()) )
-
- elif classtype == H5T_STRING:
- if self.is_variable_str():
- raise ValueError("Variable-length strings are not supported.")
- typeobj = dtype("|S" + str(self.get_size()))
-
- elif classtype == H5T_OPAQUE:
- typeobj = dtype("|V" + str(self.get_size()))
-
- elif classtype == H5T_COMPOUND:
-
- nfields = self.get_nmembers()
- field_names = []
- field_types = []
-
- # First step: read field names and their Numpy dtypes into
- # two separate arrays.
- for i from 0 <= i < nfields:
- tmp_type = self.get_member_type(i)
- tmp_type.complex_names = self.complex_names
- try:
- field_names.append(self.get_member_name(i))
- field_types.append(tmp_type.py_dtype())
- finally:
- tmp_type.close()
-
- # 1. Check if it should be converted to a complex number
- if len(field_names) == 2 and \
- tuple(field_names) == self.complex_names and \
- field_types[0] == field_types[1] and \
- field_types[0].kind == 'f':
-
- bstring = field_types[0].str
- blen = int(bstring[2:])
- nstring = bstring[0] + "c" + str(2*blen)
- typeobj = dtype(nstring)
-
- # 2. Otherwise, read all fields of the compound type, in HDF5 order.
- else:
- typeobj = dtype(zip(field_names, field_types))
-
- elif classtype == H5T_ENUM:
- # Have to recover enum dictionaries manually.
- tmp_type = self.get_super()
- try:
- typeobj = tmp_type.py_dtype()
- finally:
- tmp_type.close()
-
- elif classtype == H5T_ARRAY:
- tmp_type = self.get_super()
- tmp_type.complex_names = self.complex_names
- try:
- base_dtype = tmp_type.py_dtype()
- finally:
- tmp_type.close()
- shape = tid.get_array_dims()
- typeobj = dtype( (base_dtype, shape) )
-
- else:
- raise ValueError('Unsupported datatype class "%s"' % PY_NAMES[classtype])
-
- return typeobj
# === Python extension functions ==============================================
@@ -781,9 +848,9 @@ def py_create(dtype dt not None, object complex_names=None):
elif kind == c'c':
if length == 8:
- otype = TypeID(create_ieee_complex64(byteorder, _complex_names[0], _complex_names[1]))
+ otype = typewrap(create_ieee_complex64(byteorder, _complex_names[0], _complex_names[1]))
elif length == 16:
- otype = TypeID(create_ieee_complex128(byteorder, _complex_names[0], _complex_names[1]))
+ otype = typewrap(create_ieee_complex128(byteorder, _complex_names[0], _complex_names[1]))
else:
raise ValueError("Unsupported length %d for complex dtype: %s" % (length, repr(dt)))
@@ -802,7 +869,7 @@ def py_create(dtype dt not None, object complex_names=None):
# Strings are assumed to be stored C-style.
elif kind == c'S':
- otype = TypeID(H5Tcopy(H5T_C_S1))
+ otype = typewrap(H5Tcopy(H5T_C_S1))
otype.set_size(length)
else:
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/h5py.git
More information about the debian-science-commits
mailing list