[h5py] 158/455: Add NumPy-style coordinate indexing

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:28 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 bbaf2a763fde6a95a1e63eb0439387b9ccc6d955
Author: andrewcollette <andrew.collette at gmail.com>
Date:   Sun Nov 23 07:42:27 2008 +0000

    Add NumPy-style coordinate indexing
---
 h5py/highlevel.py            |   3 +-
 h5py/tests/test_highlevel.py |   1 +
 h5py/utils_hl.py             | 125 ++++++++++++++++++++++++++++---------------
 3 files changed, 86 insertions(+), 43 deletions(-)

diff --git a/h5py/highlevel.py b/h5py/highlevel.py
index 5a0b916..9de07e7 100644
--- a/h5py/highlevel.py
+++ b/h5py/highlevel.py
@@ -780,7 +780,8 @@ class Dataset(HLObject):
 
             size = tuple(size)
             self.id.set_extent(size)
-
+            h5f.flush(self.id)  # THG recommends
+            
     def __len__(self):
         """ The size of the first axis.  TypeError if scalar.
         """
diff --git a/h5py/tests/test_highlevel.py b/h5py/tests/test_highlevel.py
index ba6d163..f715eb1 100644
--- a/h5py/tests/test_highlevel.py
+++ b/h5py/tests/test_highlevel.py
@@ -448,6 +448,7 @@ class TestDataset(HDF5TestCase):
         slices += [ s[0], s[1], s[9], s[0,0], s[4,5], s[:] ]
         slices += [ s[3,...], s[3,2,...] ]
         slices += [ numpy.random.random((10,10,50)) > 0.5 ]  # Truth array
+        slices += [ s[0, 1, [2,3,6,7]], s[:,[1,2]], s[[1,2]], s[3:7,[1]]]
 
         for slc in slices:
             self.output("    Checking %s" % ((slc,) if not isinstance(slc, numpy.ndarray) else 'ARRAY'))
diff --git a/h5py/utils_hl.py b/h5py/utils_hl.py
index ca6ef34..a2ffe46 100644
--- a/h5py/utils_hl.py
+++ b/h5py/utils_hl.py
@@ -173,65 +173,106 @@ def slice_select(space, args):
         else:
             final_args.append(arg)
 
-    # Step through the expanded argument list and handle each axis
 
-    start = []
-    count = []
-    stride = []
-    simple = []
+    # Hyperslab selection
+
+    space.select_all()
+
+    def perform_selection(start, count, step, idx, op=h5s.SELECT_AND):
+        """ Performs a selection using start/count/step in the given axis.
+
+        All other axes have their full range selected.  The selection is
+        added to the current dataspace selection using the given operator,
+        defaulting to AND.
+
+        All arguments are ints.
+        """
+
+        shape = space.shape
+
+        start = tuple(0 if i != idx else start for i, x in enumerate(shape) )
+        count = tuple(x if i != idx else count for i, x in enumerate(shape) )
+        step  = tuple(1 if i != idx else step  for i, x in enumerate(shape) )
+
+        space.select_hyperslab(start, count, step, op=op)
+
+    def validate_number(num, length):
+        """ Make sure the given object can be converted to a positive int
+        smaller than the length.
+        """
+        try:
+            num = long(num)
+        except TypeError:
+            raise TypeError("Illegal index: %r" % num)
+        if num > length-1:
+            raise IndexError('Index out of bounds: %d' % num)
+        if num < 0:
+            raise IndexError('Negative index not allowed: %d' % num)
+
+    mshape = []
+
     for idx, (length, exp) in enumerate(zip(shape,final_args)):
 
         if isinstance(exp, slice):
 
-            # slice.indices() method is limited to long ints
+            start, stop, step = exp.start, exp.stop, exp.step
+            start = 0 if start is None else int(start)
+            stop = length if stop is None else int(stop)
+            step = 1 if step is None else int(step)
 
-            start_, stop_, step_ = exp.start, exp.stop, exp.step
-            start_ = 0 if start_ is None else int(start_)
-            stop_ = length if stop_ is None else int(stop_)
-            step_ = 1 if step_ is None else int(step_)
+            if start < 0:
+                raise ValueError("Negative start index not allowed (got %d)" % start)
+            if step < 1:
+                raise ValueError("Step must be >= 1 (got %d)" % step)
+            if stop < 0:
+                raise ValueError("Negative stop index not allowed (got %d)" % stop)
 
-            if start_ < 0:
-                raise ValueError("Negative start index not allowed (got %d)" % start_)
-            if step_ < 1:
-                raise ValueError("Step must be >= 1 (got %d)" % step_)
-            if stop_ < 0:
-                raise ValueError("Negative stop index not allowed (got %d)" % stop_)
+            count = (stop-start)//step
+            if (stop-start) % step != 0:
+                count += 1
 
-            count_ = (stop_-start_)//step_
-            if (stop_-start_) % step_ != 0:
-                count_ += 1
-
-            if start_+count_ > length:
+            if start+count > length:
                 raise ValueError("Selection out of bounds on axis %d" % idx)
 
-            simple_ = False
+            perform_selection(start, count, step, idx)
 
-        else:
-            try:
-                exp = long(exp)
-            except TypeError:
-                raise TypeError("Illegal index on axis %d: %r" % (idx, exp))
+            mshape.append(count)
+
+        else:  # either an index or list of indices
+
+            if not isinstance(exp, list):
+                exp = [exp]
+                mshape.append(0)
+            else:
+                mshape.append(len(exp))
+
+            if len(exp) == 0:
+                raise TypeError("Empty selections are not allowed (axis %d)" % idx)
 
-            if exp > length-1:
-                raise IndexError('Index %d out of bounds: "%d" (should be <= %d)' % (idx, exp, length-1))
+            if sorted(exp) != exp:
+                raise TypeError("Selection list must be provided in increasing order (axis %d)" % idx)
 
-            start_ = exp
-            step_ = 1
-            count_ = 1
-            simple_ = True
+            for x in exp:
+                validate_number(x, length)
 
-        start.append(start_)
-        count.append(count_)
-        stride.append(step_)
-        simple.append(simple_)
+            for select_idx in xrange(len(exp)+1):
 
-    space.select_hyperslab(tuple(start), tuple(count), tuple(stride))
+                if select_idx == 0:
+                    start = 0
+                    count = exp[0]
+                elif select_idx == len(exp):
+                    start = exp[-1]+1
+                    count = length-start
+                else:
+                    start = exp[select_idx-1]+1
+                    count = exp[select_idx] - start
+                if count > 0:
+                    perform_selection(start, count, 1, idx, op=h5s.SELECT_NOTB)
 
-    # According to the NumPy rules, dimensions which are specified as an int
-    # do not result in a length-1 axis.
-    mem_shape = tuple(x for x, smpl in zip(count, simple) if not smpl) 
+    mshape_final = tuple(x for x in mshape if x != 0)
+    mspace = h5s.create_simple(mshape_final, (h5s.UNLIMITED,)*len(mshape_final))
 
-    return h5s.create_simple(mem_shape, (h5s.UNLIMITED,)*len(mem_shape)), all(simple)
+    return mspace, (len(mshape_final) == 0)
 
 def strhdr(line, char='-'):
     """ Print a line followed by an ASCII-art underline """

-- 
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