dims.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. Implements support for HDF5 dimension scales.
  11. """
  12. import warnings
  13. from .. import h5ds
  14. from ..h5py_warnings import H5pyDeprecationWarning
  15. from . import base
  16. from .base import phil, with_phil
  17. from .dataset import Dataset
  18. class DimensionProxy(base.CommonStateObject):
  19. """
  20. Represents an HDF5 "dimension".
  21. """
  22. @property
  23. @with_phil
  24. def label(self):
  25. """ Get or set the dimension scale label """
  26. return self._d(h5ds.get_label(self._id, self._dimension))
  27. @label.setter
  28. @with_phil
  29. def label(self, val):
  30. # pylint: disable=missing-docstring
  31. h5ds.set_label(self._id, self._dimension, self._e(val))
  32. @with_phil
  33. def __init__(self, id_, dimension):
  34. self._id = id_
  35. self._dimension = dimension
  36. @with_phil
  37. def __hash__(self):
  38. return hash((type(self), self._id, self._dimension))
  39. @with_phil
  40. def __eq__(self, other):
  41. return hash(self) == hash(other)
  42. @with_phil
  43. def __iter__(self):
  44. yield from self.keys()
  45. @with_phil
  46. def __len__(self):
  47. return h5ds.get_num_scales(self._id, self._dimension)
  48. @with_phil
  49. def __getitem__(self, item):
  50. if isinstance(item, int):
  51. scales = []
  52. h5ds.iterate(self._id, self._dimension, scales.append, 0)
  53. return Dataset(scales[item])
  54. else:
  55. def f(dsid):
  56. """ Iterate over scales to find a matching name """
  57. if h5ds.get_scale_name(dsid) == self._e(item):
  58. return dsid
  59. res = h5ds.iterate(self._id, self._dimension, f, 0)
  60. if res is None:
  61. raise KeyError(item)
  62. return Dataset(res)
  63. def attach_scale(self, dset):
  64. """ Attach a scale to this dimension.
  65. Provide the Dataset of the scale you would like to attach.
  66. """
  67. with phil:
  68. h5ds.attach_scale(self._id, dset.id, self._dimension)
  69. def detach_scale(self, dset):
  70. """ Remove a scale from this dimension.
  71. Provide the Dataset of the scale you would like to remove.
  72. """
  73. with phil:
  74. h5ds.detach_scale(self._id, dset.id, self._dimension)
  75. def items(self):
  76. """ Get a list of (name, Dataset) pairs with all scales on this
  77. dimension.
  78. """
  79. with phil:
  80. scales = []
  81. # H5DSiterate raises an error if there are no dimension scales,
  82. # rather than iterating 0 times. See #483.
  83. if len(self) > 0:
  84. h5ds.iterate(self._id, self._dimension, scales.append, 0)
  85. return [
  86. (self._d(h5ds.get_scale_name(x)), Dataset(x))
  87. for x in scales
  88. ]
  89. def keys(self):
  90. """ Get a list of names for the scales on this dimension. """
  91. with phil:
  92. return [key for (key, _) in self.items()]
  93. def values(self):
  94. """ Get a list of Dataset for scales on this dimension. """
  95. with phil:
  96. return [val for (_, val) in self.items()]
  97. @with_phil
  98. def __repr__(self):
  99. if not self._id:
  100. return "<Dimension of closed HDF5 dataset>"
  101. return ('<"%s" dimension %d of HDF5 dataset at %s>'
  102. % (self.label, self._dimension, id(self._id)))
  103. class DimensionManager(base.CommonStateObject):
  104. """
  105. Represents a collection of dimension associated with a dataset.
  106. Like AttributeManager, an instance of this class is returned when
  107. accessing the ".dims" property on a Dataset.
  108. """
  109. @with_phil
  110. def __init__(self, parent):
  111. """ Private constructor.
  112. """
  113. self._id = parent.id
  114. @with_phil
  115. def __getitem__(self, index):
  116. """ Return a Dimension object
  117. """
  118. if index > len(self) - 1:
  119. raise IndexError('Index out of range')
  120. return DimensionProxy(self._id, index)
  121. @with_phil
  122. def __len__(self):
  123. """ Number of dimensions associated with the dataset. """
  124. return self._id.rank
  125. @with_phil
  126. def __iter__(self):
  127. """ Iterate over the dimensions. """
  128. for i in range(len(self)):
  129. yield self[i]
  130. @with_phil
  131. def __repr__(self):
  132. if not self._id:
  133. return "<Dimensions of closed HDF5 dataset>"
  134. return "<Dimensions of HDF5 object at %s>" % id(self._id)
  135. def create_scale(self, dset, name=''):
  136. """ Create a new dimension, from an initial scale.
  137. Provide the dataset and a name for the scale.
  138. """
  139. warnings.warn("other_ds.dims.create_scale(ds, name) is deprecated. "
  140. "Use ds.make_scale(name) instead.",
  141. H5pyDeprecationWarning, stacklevel=2,
  142. )
  143. dset.make_scale(name)