[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