1# This file is part of h5py, a Python interface to the HDF5 library.
2#
3# http://www.h5py.org
4#
5# Copyright 2008-2013 Andrew Collette and contributors
6#
7# License: Standard 3-clause BSD; see "license.txt" for full license terms
8# and contributor agreement.
9
10"""
11 Implements a portion of the selection operations.
12"""
13
14import numpy as np
15from .. import h5s
16
17def read_dtypes(dataset_dtype, names):
18 """ Returns a 2-tuple containing:
19
20 1. Output dataset dtype
21 2. Dtype containing HDF5-appropriate description of destination
22 """
23
24 if len(names) == 0: # Not compound, or all fields needed
25 format_dtype = dataset_dtype
26
27 elif dataset_dtype.names is None:
28 raise ValueError("Field names only allowed for compound types")
29
30 elif any(x not in dataset_dtype.names for x in names):
31 raise ValueError("Field does not appear in this type.")
32
33 else:
34 format_dtype = np.dtype([(name, dataset_dtype.fields[name][0]) for name in names])
35
36 if len(names) == 1:
37 # We don't preserve the field information if only one explicitly selected.
38 output_dtype = format_dtype.fields[names[0]][0]
39
40 else:
41 output_dtype = format_dtype
42
43 return output_dtype, format_dtype
44
45
46def read_selections_scalar(dsid, args):
47 """ Returns a 2-tuple containing:
48
49 1. Output dataset shape
50 2. HDF5 dataspace containing source selection.
51
52 Works for scalar datasets.
53 """
54
55 if dsid.shape != ():
56 raise RuntimeError("Illegal selection function for non-scalar dataset")
57
58 if args == ():
59 # This is a signal that an array scalar should be returned instead
60 # of an ndarray with shape ()
61 out_shape = None
62
63 elif args == (Ellipsis,):
64 out_shape = ()
65
66 else:
67 raise ValueError("Illegal slicing argument for scalar dataspace")
68
69 source_space = dsid.get_space()
70 source_space.select_all()
71
72 return out_shape, source_space
73
74class ScalarReadSelection:
75
76 """
77 Implements slicing for scalar datasets.
78 """
79
80 def __init__(self, fspace, args):
81 if args == ():
82 self.mshape = None
83 elif args == (Ellipsis,):
84 self.mshape = ()
85 else:
86 raise ValueError("Illegal slicing argument for scalar dataspace")
87
88 self.mspace = h5s.create(h5s.SCALAR)
89 self.fspace = fspace
90
91 def __iter__(self):
92 self.mspace.select_all()
93 yield self.fspace, self.mspace
94
95def select_read(fspace, args):
96 """ Top-level dispatch function for reading.
97
98 At the moment, only supports reading from scalar datasets.
99 """
100 if fspace.shape == ():
101 return ScalarReadSelection(fspace, args)
102
103 raise NotImplementedError()